2009.11.01

SQL Server Express Edition

11月ですね。
たまにはSEぽいことも書きましょうか。

1.SQL Server Express Edition
先日、現地のDBが溢れました。
領域フル、これ以上1行も書けないって状況です。

環境は、Windows Server 2003 上にIISのWebサーバ、
そのアクセスログをSQL Serverに保存しています。

問題だったのは、SQL ServerがExpress Editionであり、
DB領域の上限が4GBという制限があることでした。

MSの製品概要には以下の記述があります。
スケーラビリティとパフォーマンス
サポートしている CPU は 1 つだけですが任意のサーバーにインストールできます。
アドレス指定可能な RAM は 1 GB です。
4 GB のデータベース サイズ(★)

参考:Microsoft SQL Server 2005 Express Edition データシート

最後の1文、「4 GB のデータベース サイズ」ということは、
それを超えると拡張しませんよ」ってことです。

痛たたたた…。
それを現地で、しかも運用開始後
1年以上経過してから気付くってのも間抜けですね。

適切なログローテートの仕組みさえ備えていれば、
通常は起こりえないことです。

仕方ないので、300万件を超える現地テーブルに対し、
CSV形式でデータを保存した後、TRUNCATEを投げました。
初めての経験です、現地DBにTRUNCATE…。
それがどれほど恐ろしいことか…。
(参考:ユーザーの伝票明細テーブルを間違ってTRUNCATEした。 ROLLBACKも効かない。:アルファルファモザイク - 2ちゃんねるスレッドまとめブログ)

運用計画はしっかり立てましょう。

--
2.LIKEと=の挙動差異
これも現地で気付いたことです。

次のSQLの違いについてです。
1)SELECT * FROM hoge WHERE ID = 'A'
2)SELECT * FROM hoge WHERE ID LIKE 'A'
2)はワイルドカードの無いパターン検索です。
どちらもIDが「A」というデータを検索するSQLに見えます。

が、結果が異なりました。

環境は、Windows Server 2003 上の
SQL Serve Enterprise Editionです。

検索結果ですが、以下のようになります。
1)「A」、「 A」、「A 」、「 A」…
2)「A」のみ

不思議ですが、1)のSQLは複数の結果を返します。
1)の場合、「A」の前後に空白が存在するデータも
検索結果に入ってしまっています。

SQLサーバでは、"="は
「前後の空白をTRIMして検索する」らしいです。

猫目が物を知らなかっただけですが、
そもそも同じ検索処理で異なるSQLを書いてはいけない、
ということですね。

え、結末?
直しましたよ、その場でストアドプロシージャを。
コソーリと、ね。

| | コメント (0) | トラックバック (0)

2009.03.04

[C#]無効ユーザの判定・ビット演算[ActiveDirectory]

ActiveDirectory(AD)上のユーザが
有効であるか無効であるかを判定し、
有効なら無効に、無効なら有効にする
(処理自体には余り意味のない)処理です。

環境:
W2k3 Server R2 SP2(AD)
WinXP & Visual Studio 2005(C#.NET)

ユーザが有効か無効かは、
オブジェクトの userAccountControl 属性を調べますが、
この属性はビットマップ属性であるため、
16 進数のビット演算が必要になります。

ちなみに、UserAccountControl属性値については、
UserAccountControl フラグを使用して
ユーザー アカウント プロパティを操作する方法
(サポート オンライン)
をご参照ください。

で、無効ならばUserAccountControlには
ACCOUNTDISABLE(0x0002=2)が立っています。

以下、コード。
--
//ユーザオブジェクト取得
DirectoryEntry usr =
  new DirectoryEntry("LDAP://CN=Hoge,CN=users,DC=fabrikam,DC=com");

//userAccountControl値を取得
int val = (int) usr.Properties["userAccountControl"].Value;

//ADS_UF_ACCOUNTDISABLEが立っている(=無効である)場合
if ((val & (int)ActiveDs.ADS_USER_FLAG.ADS_UF_ACCOUNTDISABLE)
  == (int)ActiveDs.ADS_USER_FLAG.ADS_UF_ACCOUNTDISABLE)
{
  //ユーザー アカウントを有効にする(=フラグを解除)
  usr.Properties["userAccountControl"].Value
    = val & ~ (int)ActiveDs.ADS_USER_FLAG.ADS_UF_ACCOUNTDISABLE;
}
//ADS_UF_ACCOUNTDISABLEが立ってない(=有効である)場合
else
{
  //ユーザー アカウントを無効にする(=フラグを立てる)
  usr.Properties["userAccountControl"].Value
    = val | (int)ActiveDs.ADS_USER_FLAG.ADS_UF_ACCOUNTDISABLE;
}
//コミット
usr.CommitChanges();

--
ここでC#プログラマに余り馴染みがないのが、
論理演算子「 & | ~ 」ではないでしょうか?
基本自分をCプログラマだと思っている猫目も
ビット演算は結構不得手(^-^;)でして、
以下のページを参考にしました。
humming bird: ビット演算を理解してフラグを使いこなす [C#]
大変判りやすくまとまっています。感謝(^-^)。

アカウントの有効/無効化は以下を参考にしました。
ユーザー アカウントの有効化と無効化(MSDN)
管理者は見た!~AD と ILM 一家の秘密~
  : スクリプトセンターに挑戦!(ADSI でも論理演算って重要なんです!)

--
有効/無効化する方法については
あちこち書かれているんですが、

無効であるか?

という判定について、
C#でズバリ書かれたコードを
見つけることが出来なかったので、
復習も兼ねての自分用メモ。

C#, ActiveDirectory, ADSI

| | コメント (1) | トラックバック (0)

2008.11.19

[SQL]重複するデータ件数を集計する

以下のテーブル[LIST]で、
Typeが2件以上重複する件数を集計するSQL。

LIST:

NameType
TANAKAA
SHIKIC
MARIAA
KURIYAKAWAB
TAROO
GEMB
GONZOAB
KARAKIB

SQLは、
SELECT Type, COUNT(*) AS NameCount
FROM LIST
GROUP BY Type
HAVING (COUNT(*) > 1)
ORDER BY Type

結果:

TypeNameCount
A2
B3

丸1日悩んだ集計SQLだったのでメモ代わりに。

HAVINGなんて滅多に使わないから
普通に忘れてました…。

実行環境:SQL Server 2005

--
昨日は勢い余って
5時の始発で出社して終電で帰るという
ブッ飛んだ麻薬中毒者(?)みたいなことをしてしまったので、
今日は午前半休の上に定時退社、
実働=4時間ということをしてみました。

| | コメント (0) | トラックバック (0)

2008.09.22

[C#]ドロップダウン初期選択[ASP.NET]

C# + ASP.NET のWebアプリで、
ドロップダウンリストを初期選択させる方法を以下に記載します。

あちこちググッたんですが、
そのものズバリを記載したサイトが見つからなかったので、
或いは単なる自分用メモ。

//リスト(dropdownHoge)にアイテムが追加されているものとする
//セッション変数はHOGE

誤コード①(by 後輩):
if (!dropdownHoge.Items.FindByValue(HOGE).Selected)
{
 dropdownHoge.Items.FindByValue(HOGE).Selected = true;
}
//セッション変数HOGE(と一致する値)が選択されていなかった場合、
//HOGEと同じものを選択させようとする意図は判ります。

誤コード②(by猫目):
//Dropdownアイテム分ループ
foreach (ListItem item in dropdownHoge.Items)
{ //セッション変数と一致した場合
 if (item.Value == HOGE)
 { //一致するアイテムを選択する
  item.Selected = true;
  break;
 }
}
//VBぽい方法。
//ドロップダウンアイテム数分回して、
//一致していれば選択させることを意図しました。

①②共に
System.Web.HttpException:
DropDownList で複数項目が選択されるように指定できません。

が出ます。

正解:
int index=0;
//Dropdownアイテム分ループ
foreach (ListItem item in dropdownHoge.Items)
{//セッション変数と一致した場合
 if (item.Value == HOGE)
 { //一致するアイテムを選択する
  dropdownHoge.SelectedIndex = index;
  break;
 }
 index++;
}

これだけ。
ドロップダウンのSelectedIndexを
選択(初期表示)するItemのindexに設定するだけ。
わかってみると「なーんだ」な感じ。

C#, ASP.NET, DropdownList
--
外では雷がものすごく光ってます。
まさに風雲急を告げる感じ。

| | コメント (6) | トラックバック (0)

2006.11.20

DBConsole for Oracle Enterprise Manager

数ヶ月前から OracleDB の構築には苦労してきましたが、
中でも、最も厄介なのがOracle Enterprise Manager(EM)の環境設定、
即ち、DBConsole プロセスの環境設定と起動です。

環境:Windows 2003 Server or XP
   Oracle 10g Release 2

この EM、IE ベースで OracleDB の設定から中身のデータまで、
SQL コマンドを投げることなく視覚的に操作することの出来る
それはそれは簡易で便利なツールです。
Oracle 社謹製の SI Object Browserみたいなものですね。
…個人的には SQL*PLUS の手軽さも捨て難いですが(^-^;)

それはそれとして、この EM を動かす為には、
Oracle DBConsole というプロセスが起動していなければいけません。

が、この DBConsole が超曲者です。
ホスト名を変えれば起動しない、IP アドレスを変えても起動しない、
しまいには、LAN ケーブルが抜けてたりしててもコケる困ったちゃんです。

特に、一旦おかしな設定で動いてしまったら、
最悪、Oracle から再インストールしなければ
まともに動かないというじゃじゃ馬ぶり。

以下、狂った DBConsole を何とか正常に戻せる(かもしれない)
復活の呪文を記そうと思います。

まず、DBConsole がまともに動いているかどうか確かめるには、
コマンドプロンプトから以下を叩きます。

>emctl status dbconsole

正常であれば、以下の様に出力されます。
Oracle Enterprise Manager 10g Database Control Release 10.1.0.2.0
Copyright (c) 1996, 2004 Oracle Corporation. All rights reserved.
http://hostname:5500/em/console/aboutApplication
Oracle Enterprise Manager 10g is running. ←※
-----------------------------------
Logs are generated in directory D:\oracle\product\10.1.0\db_1/hostname_orcl/sysman/log

が、プロセスが起動していない場合、最終行(※)に
Oracle Enterprise Manager 10g is not running.
と出力されます。

起動していなかった場合、DBConsole を起動してみます。
コマンドは以下です。
>emctl start dbconsole

正常に起動する場合、以下の様に出力されます。
Oracle Enterprise Manager 10g Database Control Release 10.2.0.1.0
Copyright (c) 1996, 2005 Oracle Corporation. All rights reserved.
http://ホスト名:アドレス/em/console/aboutApplication
Starting Oracle Enterprise Manager 10g Database Control ...OracleDBConsoleorcl
サービスを開始します...................
OracleDBConsoleorcl サービスは正常に開始されました。

が、DBConsole の環境が狂っている場合、
サービスを開始します...................................................................................(延々終わらない…5分程度?)

OracleDBConsoleora101db サービスを開始できませんでした。

サービス固有のエラーが発生しました: 3
などと出力され、哀しい気分にさせられます。

上記のようになってしまうと、
OS の 管理ツール>サービス から OracleDBConsole を選んで起動しても、
延々「開始中」となるだけで、正常起動は望めない状態、
このままだと OS 起動時の負荷を上げ、エラーイベントを吐き出すのみという
単なるお荷物に成り下がります。

そこで、復活の呪文を試してみましょう。
コマンドプロンプトより、以下の様に入力します。
(リスナーが起動していること)

>set oracle_sid=XXXXX(SID)
>emca -deconfig dbcontrol db
(SIDを聞かれます→入力し、'y')
>emca -config dbcontrol db
(SID、リスナーのポート、SYSのパスワード等を聞かれます→入力し、'y')

暫くすれば、DBConsole は正常に起動する(している)筈です。
(emctl status dbconsole で見ると、deamon がどーとか出ますが、、、EM は使えます)

その後、
>emctl secure dbconsole
で DBConsole をセキュア化する等の再設定を行います。
(SYS と OS のパスワード、ホスト名等を聞かれます)

上記の、
emca -deconfig/-config dbcontrol db
のコマンドですが、DB Control の再構築を行うコマンド(らしい)です。

EM が使えなくて Oracle の再インストールを考えているなら、
上記の復活の呪文を試してみてもいいかもしれません。
猫目の場合、2台試して双方 DBConsole がまともに動く様になりました。

リポジトリの再構築(emca -config dbcontrol db -repos recreate)とかも
試してみたんですが、どうも DBControl だけの方が良いみたい。

なお、最後になりますが、呉々も自己責任でお願いします。
御利用は計画的に…。
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
今日のエントリはある意味すごいかも。
…単に自分用のメモ、という話も(^-^;)。

| | コメント (7) | トラックバック (2)

2006.06.08

ソフトウェアの不具合

某エレベータの事故は制御するソフトウェアの不具合らしいと、、、

それを読んで、ふと思い出したのが2年前のある記事。

ある携帯電話でメールの文章を打っているとき、
 かぜがなおる
または
 ひょうかがわかれる
を入力して変換しようとすると、
書いていた文章が全てクリアされ、
待ち受け画面に戻ってしまうという不具合。

かぜが」と「なおる」とか、
ひょうか」+「」+「わかれる」の様に、
文節で区切って変換すると発生しない様子。

参考:ITmediaモバイル:V602SHで「かぜがなおる」を入力・変換すると誤動作
   「V602SH」の一部事象について(ボーダフォンからのお知らせ)


…かなり限定的。
これって仕様(仕込み)でしょう、たぶん。

恐らく、以下の様な超レアケースのコードが書いてあるに違いない。
If (strWork = "かぜがなおる")
Or (strWork = "ひょうかがわかれる") Then
  Goto Error
End if


…風邪が治らず、評価が分かれたんだね、きっと(゜ーÅ)ホロリ


一口にソフトウェア開発とは言っても、
バグを出すと誰かが死ぬってのは相当に責任が重くて、
辛いことでしょうね。

が、この業界、どんなに社会的に重要なシステムの開発に携わろうと、
こと末端に至れば、その重責故に給与が高くなる、なんて事は決してないわけで。
要は、何作っても貰える金額は一緒。
それがプログラマという生き物の一面。


エレベータについては仔細は不明なれど、
「かぜがなおる」を仕込む気持ちは判らないでもないかな。

| | コメント (0) | トラックバック (1)