ちゃっぴの監禁部屋

ガチガチに締めすぎて動きがとれなくなる。。。

ホーム 連絡をする 同期する ( RSS 2.0 ) Login
投稿数  405  : 記事  5  : コメント  12114  : トラックバック  134

ニュース

記事カテゴリ

書庫

日記カテゴリ

Communities

Personal Information

2009年6月14日 #

ネタ元: 横持ちと縦持ち_その後2_SQL文は侮れない

表題のとおりなんですが、ad-hoc query なんてものは無くしちまえ!というのがおいらの意見。

唯一の例外は、運用や試験目的で sqlcmd を発行する時くらいでしょうか。

SQL 構文を教えるのが目的なら当然必要ですが、別の言語からの呼び出し方を教えるなら ad-hoc query を発行するやり方を教えると有害な面の方が大きいと思う。

というのは、下記弊害があるから。

  • SQL injection

    Parameterized query を利用したからと言って SQL injection 全てを防げるわけではありませんが、間違いなく有効な方策です。SQL injection を防止するためには、parameterized query の発行方法と LIKE での escape を教えればいいかと。これをやっておくと code review で脆弱性を探すのが圧倒的に楽になるという利点も生まれます。何も考えずに ad-hoc query を発行した場合の結果は言わずもがな。

  • Compile 時間の増大

    Ad-hoc query の場合、procedure cache に一致したものが無いとその都度 compile されます。この procedure cache というのが厄介で、SQL Server の場合、parameters が一個でも違っていたら一致しないのは当然として、case-sensitive なので SQL 構文が大文字小文字で異なっているだけで一致しないと判断されます。

  • Cache 有効活用

    SQL Server 64 bit 環境だと procedure cache が事実上無制限に拡張します。32 bit 環境だと Windows 32 bit 環境の制約により 2 GB までに制限されていましたけど。ということで、procedure cache が無制限に拡張されるため、本当に必要な data cache 領域が圧迫されて cache を有効活用することができません。

もっとも、上記弊害まで一緒に教えるなら問題ないんですけどね。

このような問題があるので、この手の書き方を教える場合、ad-hoc query 発行方法は必須では無いです。ほとんどの処理は parameterized query で代用できるのでこっちこそ必須とすべきでしょう。両方ちゃんと教えるならともかく、ad-hoc query 発行方法だけ教えるのはあり得ない。

なお、上記は SQL Server 2005 までの環境を前提にしています。SQL Server 2008 ではちゃんと確認していないのでどなたか確認をお願いたします。おそらく同じだと思いますけど。。。

posted @ 21:52 | Feedback (14)

Visual Studio では compile option 「char 型を既定で unsigned (/J)」によって変わりますけど、/J を指定していない場合、char と signed char は同じだと思っていました。ところが。。。

signed char string[] = "あいうえお";
char * pString = string;

この結果は

error C2440: '初期化中' : 'signed char [11]' から 'char *' に変換できません。

上記 error で失敗します。

下記はあまりにも当然ですけど、成功します。

char string[] = "あいうえお";
char * pString = string;

上記は Visual Studio 2008 Professional Edition SP1 で確認しています。

Compile option に /J をつけていない場合、char == signed char (typedef char signed char な感じ) だと思っていたけど、違うみたいですね。なんの目的があるんでしょう?

posted @ 20:41 | Feedback (8)

String コンストラクタ を読んでいて思ったこと。

わかりにくい!

例えばこれ! String コンストラクタ (Char*)

Char * って System::Char なので Unicode だろうから、WCHAR すなわち wchar_t というところまではすぐにわかるけどね。System::Char の pointer って正直何よ? って感じが。。。

とはいえ、C++ の宣言は下記になっているから許せるけど。

[CLSCompliantAttribute(false)] public: String( wchar_t* value )

でも、最初に探すとき wchar_t * (WCHAR *, LPWSTR) で調べると思うんですよね。C++/CLI 以外でこんな constructor まず使わないと思うので、wchar_t * でいいんじゃないかと。

もっとわかりにくいのは String コンストラクタ (SByte*) ! 何これ! System::SByte 構造体 なんて普通知らんじゃないかな?

で、参照すると IEquatable 。 ふむふむ、signed char と互換性があるのね。って、ここまで references 掘り下げないとわからないのかよ!

String コンストラクタ (signed char *) にしてくれないかなぁ~と。

ここまでやってようやくわかったんだけど、要するに System::String constructor 使って Unicode だろうと MBCS だろうと C の文字列から System::String に変換できるのね。

char string1[] = "あいうえお";
wchar_t string2[] = L"あいうえお";
System::String ^ clrString1 = gcnew System::String(string1);
System::String ^ clrString2 = gcnew System::String(string2);
System::Console::Write("MBCS:\t{0:s}\nUnicode:\t{1:s}\n", clrString1, clrString2);

上記ができる説明をしたつもりだったけど、実際は全然違うみたい。

signed char string1[] = "あいうえお";

にすると compile eroor になるし。。。正確な情報どなたか教えてください。

posted @ 15:40 | Feedback (13)