4

メソッド設計に関する以前の質問の1つに続いて、SQLクエリを単純な文字列ではなくパラメータ化されたクエリとして実装するようにアドバイスされました。

これまでパラメータ化されたクエリを使用したことがないので、簡単なものから始めることにしました。次のSelectステートメントを使用します。

String select = "SELECT * FROM ? ";

PreparedStatement ps = connection.prepareStatement(select);
ps.setString(1, "person");

これにより、次のエラーが発生します:「[SQLITE_ERROR] SQLエラーまたはデータベースがありません(「?」の近く:構文エラー)」

次に、追加の基準を持つ修正バージョンを試しました。

String select = "SELECT id FROM person WHERE name = ? ";

PreparedStatement ps = connection.prepareStatement(select);
ps.setString(1, "Yui");

このバージョンは正常に動作します。私の最初の例では、パラメーター化されたクエリのポイントが欠落していますか、それとも正しく構成されていませんか?

ありがとう!

4

3 に答える 3

9

簡単に言えば、SQLバインドはテーブルをバインドできず、where句の値のみをバインドできます。これには、準備されたSQLステートメントの「コンパイル」に関連する内部的な技術的理由がいくつかあります。一般に、パラメーター化されたクエリは、SQLインジェクションを防ぐことでSQLをより安全にするように設計されており、クエリをより「モジュール式」にするという副次的な利点もありましたが、テーブル名を動的に設定できるほどではありません(テーブルがどうなるかはすでにわかっています)。

于 2011-03-30T19:18:50.627 に答える
2

PERSONテーブルのすべての行が必要な場合は、次のようにする必要があります。

String select = "SELECT * FROM person";

PreparedStatement ps = connection.prepareStatement(select);

変数バインディングは、上記の他のようにテーブル名を動的にバインドしません。テーブル名が変数としてメソッドに入力されている場合は、次のようにクエリ全体を作成できます。

String select = "SELECT * FROM " + varTableName;
PreparedStatement ps = connection.prepareStatement(select);

パラメータ化されたクエリは、テーブル名ではなく、フィールド名をクエリするためのものです。

于 2011-03-30T19:35:18.550 に答える
1

プリペアドステートメントは引き続きSQLであり、適切なwhere句を使用して作成する必要があります。つまり、x=yです。それらの利点の1つは、送信されるたびにではなく、最初に表示されたときにRDMSによって解析されることです。これにより、異なるバインド値を使用した同じクエリの後続の実行が高速化されます。

于 2011-03-30T19:21:47.933 に答える