質問: beforeWhereSql + whereCondition; /* SQL 実行処理*/ return 検索結果 } ``` Tは、検索結果の型です。 外からwhereConditionを渡す場合に、利用側でこのstringを作成する必要がありますが、 後でこのwhereCondition部分を指しかえれるような仕組みを検討しています。 目的は、OracleでもMySQLにも対応できるように、SQL文は後から差し替えたいです。 なお、whereCondition部分は、利用アプリ側で動的に作成する必要があります。 .Net Frameworkは4.6になります。 何かノウハウ等ありましたら情報を頂けると幸いです。
回答: 前提としてクエリーの条件自体を文字列として指定させるべきではありません。 まず、第三者から渡されたSQLフラグメントをそのまま使用することは深刻なセキュリティホールになりえます。一番単純な例としては ``` "SELECT * FROM table1 " + "WHERE 1 = 1; DROP TABLE table1"; ``` のように別のSQLステートメントを追加されることも考慮してください。 このような攻撃に対しては引数の値が文法的に問題ないか検証する必要があるのですが、究極的にはSQLパーサーを作らなけれなならないため筋の良い方法とは言えません。`WHERE`句をそのまま受け取るメソッドを作るとしても、`public`にすべきではありません。 ですので引数を単純な値として扱うためにパラメーターを使用して ``` if (value != null) { sql += " AND Hoge = :value"; dbCommand.Parameters.Add(":value", value); } ``` のようにSQL生成メソッド側で想定している条件に渡された値を入れる形にしなければなりません。このパラメーターの書式はRDBMSごとに異なりますので、仮にこの方針で作るとしたらこの処理は差し替え可能にする必要があります。 以上の理由により文字列処理によるSQL生成には限界がありますし、現代的な方法とは言えません。行ってしまえば**極力SQLを文字列として扱うべきでない**というのがノウハウです。 一方Entity Frameworkに代表されるORMでは検索条件として文字列ではなく`System.Linq.Expressions.Expression`型を採用しています。これはC#のラムダ式ですので、多彩な条件を表すことが出来ます。単純な検索であれば ``` // Expression> predicate = e => e.Hoge == value; db.Table1.Where(predicate).ToList(); ``` だけで済みます。RDBMSは基本的には参照ライブラリと接続文字列周りの設定を入れ替えれば変更可能です。 またORMであっても`DataBase.SqlQuery`(EFの場合)のようなメソッドなどから文字列によるクエリーも提供していることが多いので、切り替えられるところからORMに変更していくのが良いのではないでしょうか。