2016-11-09 7 views
0

PreparedStatementを使用してSQLインジェクションに役立ついくつかのコードをSQLで記述しています。データベース内のPreparedStatementとデータベース名とカラム名の変数

例:

stm = c.prepareStatement("UPDATE " 
       + listResults.get(i).get(TemplateFile.TYPEOFPLAY).toLowerCase() 
       + " SET score=? WHERE player_name_fkey=? AND school_name_fkey=? AND tournament_number=?;"); 

stm.setInt(1, Utilities.readNumber(listResults.get(i).get(TemplateFile.TOURNAMENT + j - 1))); 
stm.setString(2, listResults.get(i).get(TemplateFile.NAME)); 
stm.setString(3, listResults.get(i).get(TemplateFile.SCHOOL_NAME)); 
stm.setInt(4, j); 

私の質問は以下の通りです:パラメータ(?記号)はデータベース名と列のために使用することができるようにするPreparedStatementオブジェクトを取得する方法があります。 例えば:

stm = c.prepareStatement("UPDATE ? SET score=? WHERE player_name_fkey=? AND school_name_fkey=? AND tournament_number=?;"); 

stm.setString(1, listResults.get(i).get(TemplateFile.TYPEOFPLAY).toLowerCase()); 
stm.setInt(2, Utilities.readNumber(listResults.get(i).get(TemplateFile.TOURNAMENT + j - 1))); 
stm.setString(3, listResults.get(i).get(TemplateFile.NAME)); 
stm.setString(4, listResults.get(i).get(TemplateFile.SCHOOL_NAME)); 
stm.setInt(5, j); 

それはそんなに良く見えると同様に読みやすくなります。

ありがとうございました!

+0

大変お答えいただき、ありがとうございました。 –

答えて

1

に参加します。 PreparedStatementでは列の値のみをバインドできます。あなたは、エンドユーザーからのテーブル名を取得されていません場合は、エンドユーザーからのテーブル名を取得している場合は、以下の

String query = "UPDATE <tablename> SET score=? WHERE player_name_fkey=? AND school_name_fkey=? AND tournament_number=?"; 
query.replace("<tablename>", listResults.get(i).get(TemplateFile.TYPEOFPLAY).toLowerCase()) 
c.prepareStatement(query); 

、そしてテーブル名のホワイトリストを持っているし、ホワイトリスト

であなたの入力を確認することができます
1

この種のコーディングは、「動作しています」とさえ少し前です。 iBatisやHibernateのように、ORM - Object/Relational Mapperの使用を検討しましたか?それはあなたが考えているよりも "大きなコミットメント"の変化だと思っていますが、独自の例の1つを使用するには、SQLを含むXMLを少し使って、かなり平易なSQLを見てください:

<select id="getProduct" parameterClass="java.lang.Long" resultClass="com.example.Product"> 
select PROD_ID as id, 
      PROD_DESC as description 
     from PRODUCT 
    where PROD_ID = #value# 
</select> 

そして、 "#値#" トークンがあることを指定するためのコードを呼び出す:私はリンクをチェックしたよう

Product resultProduct = (Product) sqlMapClient.queryForObject("getProduct", 123); 

、ここではJavaのルートが維持されている - 積極的 - で:

http://blog.mybatis.org/

しかし私は元のWikiの例を残していますが、それはより明確な例だと思います。

FWIW私はこれを大いに利用しており、優れた作業をすることができました。明確でフォーマットされたプレーンテキストのSQLを適切に維持する能力は非常に大変です。 https://en.wikipedia.org/wiki/IBATIS#Usage

1

いいえ、PreparedStatement parametrizesのみの列の値、何もない:から撮影

。通常、あなただけの列名のようにそれをハードコーディングするからテーブル名を設定

が動的に、設計上の問題を示すかもしれない、あなたがそれを行うことができないなど

関連する問題