質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

7回答

320閲覧

SQL文にFROM,ONやANDを変数に代入するメリットとは

TAKAYASU

総合スコア146

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

1クリップ

投稿2018/02/09 03:54

いつもお世話になってます。
検索しても望む記事が見つからなかったので質問させていただきます。

SQL文を作成する際、FROM句等をを変数に代入し、文字列連結するコードがあるとします。

C#

1//このコードは質問用に作られたコードです。 2private void foo() 3{ 4 string sql = ""; 5 string sqlFrom = " FROM "; 6 string sqlInnerJoin = " INNER JOIN "; 7 string sqlOn = " ON "; 8 string sqlAnd = " AND "; 9 10 sql += "SELECT "; 11 sql += " A.* "; 12 sql += sqlFrom; 13 sql += " table_A A "; 14 sql += sqlInnerJoin; 15 sql += " table_B B "; 16 sql += sqlOn; 17 sql += " A.ID = B.ID "; 18 sql += sqlInnerJoin; 19 sql += " table_C C "; 20 sql += sqlOn; 21 sql += " B.ID = C.ID "; 22 sql += "WHERE "; 23 sql += " A.name = 'hoge' "; 24 sql += sqlAnd; 25 sql += " A.age = 20 "; 26 }

上記コードでは一部SQL文が内部結合から外部結合(ANDからORでも良い)に変更する修正が入った場合、変数の値を変更するだけでは対応しきれないと考えています。

接続詞を変数に代入することにはどの様なメリットがあるのでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答7

0

そもそも論ですが、(C言語や素のPHPのように機能が少ない環境は別として)SQLを文字列として組み立てること自体、XSSの混入などの危険もあるので、あまりよいコーディングスタイルではないと考えます。

C#であればLINQもありますし、その他の言語でも高機能なクエリビルダが存在することもあります。

投稿2018/02/09 04:20

maisumakun

総合スコア145123

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TAKAYASU

2018/02/09 07:03

仰る通りで、私個人もあまりよいコーディングスタイルではないと思います。 回答ありがとうございました。
guest

0

コーディング方法は十人十色で見やすいかどうかは個人が決めることで
「これが正解!」というものはないという前提ですが、
個人的には提示されているコーディングにメリットや良さをほとんど感じません。
「メリットがあるか」と聞かれれば「ないと思います…」というのが
正直なところです。あくまで個人的な主観です。orのカッコとかどうすれば
いいのかとか色々と考えてしまいますね。

投稿2018/02/09 04:11

sousuke

総合スコア3828

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TAKAYASU

2018/02/09 07:06

確かに、見やすいかどうかは個人のさじ加減によるものだと思います。 同じくこの様なコードを見ると、こんなケースの場合どう修正するんだろう。。。と考えてしまいます。 回答ありがとうございました。
guest

0

少なくとも、ご質問のコード例では何か意味があるようには思えません。

SQL文の作成で各行を+=でつなげるやり方だと前後に空白を入れないとエラーになってしまうので、あらかじめ前後に空白を入れた状態のFROMとかANDとかを用意してエラーのリスクを減らそうとしているのではないかとも思ったのですが、よく判りません。もっと良いやり方は他にいくらでもありますし。

投稿2018/02/09 04:44

catsforepaw

総合スコア5938

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TAKAYASU

2018/02/09 06:59

私も +=のやり方は好かないです。 質問のようなコードを多数見かけたので質問させていただきました。 回答ありがとうございました。
guest

0

現実的なメリットはほどんとないと思われます。
この手のコードは私も書いたことがありますし、それより多く見てきました。

実際の現場のことを知らないで断言すべきではないかもしれませんが、この手の場合は延々と言い訳が続くので断言した方が良いと考えています。

このような組み方をする場合、後で変更があった場合に対応が簡単であるという主張がなされます(&したことがあります)。その場合、多くの場合は変更が必要になることはありません。単に、可読性を損ねます。また、実際に変更があった場合のほとんどは、要件としては不十分で変数のところをいじったくらいでは何ともなりません。そして多くの場合、何もせずにシンプルなコードを保っていた場合に比べて変更が大変です。

このことをYAGNI(You ain't gonna need it)と呼びます。

その他の点についても、老婆心がもたげておりますが、(長くなることもあり)口をつぐむことにします。

投稿2018/02/12 13:24

iwamoto_takaaki

総合スコア2883

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TAKAYASU

2018/02/13 00:21

回答ありがとうございます。 YAGNIの存在は知ってましたが、実際はこのようなコードがそれにあたるのですね。 大変勉強になりました。 ありがとうございます。
guest

0

ベストアンサー

個人的には、動的SQLを生成する場合、生成されるSQLがイメージできる可読性を重視します。

例示されたコードだと、動的にする必要もないサンプルなので、判断できませんが、
可変となる要素は分岐が多そうだと変数する場合が多いです。

テーブルを切り替えるとか条件を変えるとかにはなりますけど、Fromとかand,orなんかを変数にして使い分けるメリットは思いつきません。可読性も下がる気がしますし。

投稿2018/02/09 05:00

sazi

総合スコア25138

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TAKAYASU

2018/02/09 06:53 編集

回答ありがとうございます。 質問のコードが多用されている箇所を発見し、そういうものがあると考えたのですが 皆と考えが一致していて安心しました。
guest

0

これ ↓ くらいだったら、まあ「AND か OR かを可変にしたかったんだな・・・」と思いますが・・・

csharp

1/* 2 ★ちなみに 例として書きましたが、実際には 以下のような書き方は 3 ★SQL インジェクションの恐れ等あるのでだめです。 4*/ 5private void foo(string category, string kubun, bool isAnd) 6{ 7 string sql = ""; 8 string andor = (isAnd ? " AND " : " OR "); 9 10 ... 11 12 sql += " WHERE ("; 13 sql += " X.Category = '" + category + "' " + andor + " X.Kubun = '" + kubun + "' "; 14 sql += ")"; 15 16 ... 17}

提示されたコードだと、流石にメリットは感じられないですね・・・

既存ソースでこういう書き方をしているところがあったとかですかね。
なんでしょうね?

投稿2018/02/09 04:57

編集2018/02/09 04:59
sk_3122

総合スコア1126

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TAKAYASU

2018/02/09 06:57

私もANかORを可変という話でしたら、多少なりとも判る気がします。 仰る通りこういう書き方をしている箇所が多数あったので質問させていただきました。 回答ありがとうございました。
guest

0

単純にメモリ節約を考えたぐらいしか頭に浮かびません...。変数に定義すれば使い回すことが出来ますが今度はコード量が増えるのであまり意味ないと思いますが...

投稿2018/02/09 04:07

unz.hori

総合スコア1057

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TAKAYASU

2018/02/09 07:08

メモリ節約ですか・・・盲点でした。 今後を考えなければこのようなコードもあり(?)なのかもしれないですね・・・ 回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問