33
31

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[C#]スマートなSQLの書き方

Last updated at Posted at 2019-02-01
変数
int id = 1;
string name = "yamada";
bad
string sql = "";
sql += " SELECT";
sql += "   id";
sql += "   , name";
sql += " FROM";
sql += "   hoge h";
sql += " WHERE 1=1";
sql += "   AND h.id   = "  + id;
sql += "   AND h.name = '" + name +"'";
good
var sql = new StringBuilder();
sql.AppendLine(" SELECT");
sql.AppendLine("   id");
sql.AppendLine("   , name");
sql.AppendLine(" FROM");
sql.AppendLine("   hoge h");
sql.AppendLine(" WHERE 1=1");
sql.AppendLine(string.Format("   AND h.id   = {0}", id));
sql.AppendLine(string.Format("   AND h.name = '{0}'", name));
best
// 「@」をつけると逐語的文字列リテラルとなります。
// 文字列内ではエスケープシーケンスが不要になり、改行も可能になります。
// また、C#6.0からは「$」による文字列埋め込みが使えます。
// (SQLインジェクション対策としては、生の文字列埋め込みではなくDBパラメータの利用が推奨です。)
// $@が正解ですが、@$とするとコンパイルエラーを起こすので注意。
string sql = $@"
 SELECT
   id
   , name
 FROM
   hoge h
 WHERE 1=1
   AND h.id   = '{id}'
   AND h.name = {name}
";

badなんかはやめてくださいね。
文字列連結ごとに新たにオブジェクトを生成するのでかなり遅くなります。

goodではStringBuilderオブジェクトを使っているので
速度的には速くなりましたが可読性は悪いです。
なお、文字列は一度にa + b + cなどと連結するのが
最もパフォーマンス的には優れるそうです。

bestは文字列を一度で生成し、かつシンプルで可読性も一番ですね。

また余談になりますが、WHERE句に1=1とつけることで
WHERE条件の先頭へ条件を追加する場合に
SQLを修正する手間が省けます。(行入れ替えも可能です)
' OR 1=1 --とすると、SQLインジェクションですね。悪用厳禁。

33
31
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
33
31

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?