2012-07-03 3 views
27

Java PreparedStatmentオブジェクトを使用して、一連のバッチ処理されたINSERTクエリを作成しています。クエリステートメントは、その両方のフィールドの値とテーブル名は、変数(つまり、ある... ...フォーマットのJavaプリペアドステートメントのtablename変数の使用方法insert

String strQuery = "INSERT INTO ? (col1, col2, col3, col4, col5) VALUES (?,?,?,?,?,?);"; 

です。私は、それぞれのインサートがに送られますその同じ列の形式で複数のテーブルを持っています異なるもの)。私が "?"を削除すれば、実行することができます。テーブル名の変数とハードコードが、それぞれ準備されたステートメントは、別のテーブルに挿入されますので、どのように私はこれが動的にさせることができます

stmt.setString(1, "tableName1"); 

...私はすぐに使用してバッチクエリを実行する前に取り込む変数を維持する必要があります変えてください?

答えて

37

できません。 String.formatを使用して文字列連結/プレースホルダを使用してSQLを構築する必要があります。準備された文は、表名ではない列値用です。

+2

ありがとうございました...それぞれの行の変数を交換する時点まで挿入したいtablenameがわからないので、DBストアドプロシージャ内に挿入するのが最善の方法です。次に、各行のすべてのパラメータをストアドプロシージャに渡し、DBにtablename操作を処理させます。とにかく人々の応答に感謝します。 :-) – ForestSDMC

+13

ダイナミックテーブル名でSQLインジェクションの保護が不可能なのでしょうか? –

+0

@リチャード私は同じ結論に達しました。それは馬鹿しく聞こえますが、少なくとも、データベース内の使用可能なテーブルのリストに対してテーブル名をチェックする方が簡単です。 – JulienD

-3

あなたは、元の文字列に追加する必要があります:あなたはstrQueryでセミコロンを

String tableName = "some_table_name"; 
// some other code 
String strQuery = "INSERT INTO " + tableName + " (col1, col2, col3, col4, col5) VALUES (?,?,?,?,?,?);"; 

必要がありますか? (あなたがするかもしれない、それはちょっと私には奇妙に見えます:-))

+6

を知るようになったときに交換してください。この回答を使用しないでください、キッズ! – SigmaX

+6

...それはあなたのtableNameがどこから来るかによって異なります。それがユーザーまたは信頼できないクライアントから来ている場合、私はあなたに同意します。しかし、それがあなた自身のメソッドの中に含まれている場合、Stringの不変性は、それが確実に安全であることを意味します。 –

+0

技術的には真です。しかし、良い答えにはまだ大きな脂肪免責条項が必要です。「原則として、動的SQLクエリの使用を避けてください。期間は安全ではないことが広く認識されていますので、実行していることを正確に把握してください。 – SigmaX

-2

テーブル名はパラメータとして使用することはできません。それはハードコードされている必要があります。

String tableName = "tableName1"; 
String strQuery = "INSERT INTO " + tableName + " (col1, col2, col3, col4, col5) VALUES (?,?,?,?,?,?);"; 
+7

SQLインジェクションに脆弱です。この回答を使用しないでください、キッズ! – SigmaX

-1

1つの選択肢は、String.format次のようになります。

例えば

String sql = String.format("INSERT INTO $1%s (col1, col2, col3, (etc)", myTablename); 
+15

SQLインジェクションに脆弱です。この回答を使用しないでください、キッズ! – SigmaX

+12

これはいつもの "ああ、私はSQLインジェクションが何であるか知っている"というパラノイアです - それはmyTablenameがどこから来るかによってまったく異なります。 – davidfrancis

+3

合意。しかし、ほとんどのセキュリティ上の問題と同様に、Q&Aサイトの訪問者の大部分は、myTablenameがどこから来るのかを気にする必要があることを理解していません。したがって、答えは適格である必要があります。 – SigmaX

11

テーブル名の代わりにプレースホルダを使用し、それをあなたのタブ名と置き換えることができます。

String strQuery = "INSERT INTO $tableName (col1, col2, col3, col4, col5) 
        VALUES (?,?,?,?,?,?);"; 

およびuはテーブル名

SQLインジェクションの脆弱性
String query =strQuery.replace("$tableName",tableName); 
stmt =conn.prepareStatement(query); 
+27

SQLインジェクションに脆弱です。この回答を使用しないでください、キッズ! – SigmaX

+7

ただし、$ tablenameがユーザーの入力から取得されている場合に限ります。しかし、ラジオボタン選択のようなものが列挙子の値を返すか、$ tablenameの可能な値を定義されたセットに制限する他の方法があれば問題ありませんか? – Toadfish

+9

@SigmaX SQLインジェクションに脆弱ではないあなたのソリューションは何ですか? – Mahdi

関連する問題