2


0

準備済みステートメントとは何ですか? 動的SQLとはどう違うのですか?

重複する質問はありませんでしたが、誰かがこれらの周りの良い例と特別なベストプラクティスを提供できるかどうか疑問に思いました。

3 Answer


2


準備済みステートメントは、データベースに対して複数回実行できる*プリコンパイル済み*ステートメントであり、SQLServerは実行するたびに異なる実行プランを解析または生成しません。 通常、クライアントコンテキストで準備されたステートメントを実行します(JDBC、ADO.NET、ODBCまたはその他のクライアントアクセステクノロジを使用)。

Javaで準備されたステートメント(もちろんJDBCを使用)は次のようになります。

PreparedStatement ps = conn.prepareStatmente("insert into t(field1) values (?)");
ps.setString(1, "Hello");
ps.executeUpdate();
ps.setStrgin(2, "World");
ps.executeUpdate();
ps.close();
// two rows will be inserted into table t:
// field1 => "Hello"
// field1 => "world"

Dynamic SQLは、動的変数に保存されている任意のSQL文を実行する機能です(つまり、 SQLServerのストアドプロシージャまたは関数内の文字列)。 提供されているリンクでいくつかの例を見つけることができます。


1


いくつかのコンテキストで説明する方が簡単でしょう…​

Java、PreparedStatementsでは、Java文字列内のSQL文であり、単一引用符のエスケープを心配せずに移入できるプレースホルダをサポートしています。 .NETにはPreparedStatement構文もあります

_ 準備された実行は、同じパラメーター化されたSQLステートメントを繰り返し実行するために、アプリケーションによって一般的に使用されます。 ステートメントは1回しかコンパイルされず、直接実行されるステートメントは実行されるたびにコンパイルされるため、3回または4回以上実行されるステートメントの準備済み実行は直接実行よりも高速です。 また、準備された実行により、ネットワークトラフィックを削減できます。これは、ドライバーがステートメントを実行するたびに、SQLステートメント全体ではなく、実行プラン識別子とパラメーター値をデータソースに送信できるためです。 _

ストアドプロシージャを使用する前のステップ…​

動的SQL

動的SQLは基本的に、文字列データ型として宣言されたSQLです。実行前にカスタマイズできます。 動的な列やテーブルの参照などの処理を実行する場合は、動的SQLを使用する必要があります。 たとえば、 `FROM`句のテーブルを表す文字列変数をサポートするSQLはありません(サポートされている場合、テーブル値変数は例外です)。

SQL Serverでの動的SQLに関して、「EXEC」と「EXEC sp_executesql」の違いを知ることが重要です。 「EXEC sp_executesql」はSQL Server 2005に追加されました。SQLServerの動的SQLについては、優れた記事http://www.sommarskog.se/dynamic_sql.html [動的SQLの呪いと祝福]で詳しく読むことができます。


0


PreparedStaementは、上記の回答ですでに説明したプリコンパイル済みクエリを提供する言語構成体です。 プリペアドステートメントを使用することの非常に重要な利点の1つは、悪意のあるSQLインジェクション攻撃からユーザーを守ることです。 How? 値を入力できるプレースホルダーのみがあり、クエリを変更する他の方法(プリコンパイル済み)はありませんが、ステートメントの場合はクエリ文字列を変更できます。 例:

テーブルを更新するクエリがあります-

UPDATE table_name SET col1 = 40 WHERE id = 'A001';

これは次のように(悪意を持って)変更できます-

`UPDATE table_name SET col1 = 40 WHERE id = 'A001'; DROP TABLE table_name; `

そして、あなたのテーブルはなくなりました!

動的クエリは、値を使用する代わりにバインド変数を使用できるクエリの作成に役立つデータベース構造です。 これらは特にPL / SQLコードで使用されます。 DDLステートメントの実行にも役立ちます。 サンプルコード(Oracle):

`ip_job_name:= 'APP_EXTRACT'; lv_query:= 'SELECT 1 FROM user_table WHERE table_name =:tab_name'; `

ベギン

EXECUTE IMMEDIATE lv_query INTO lv_tab USING ip_job_name;

即時「ドロップテーブル」を実行|| ip_job_name;

例外

NO_DATA_FOUND THEN NULLの場合;

END;