2013-05-20 9 views
5

JDBC SQLクエリで文字列を使用する方法について質問があります。ここには2つの例があり、私は両方が働くことを期待していますが、そうではありません。

tabl = "Action" 
    query = "SHOW FULL COLUMNS FROM `${tabl}`;" 
    println " "+ query 
    dbConnection.eachRow(query){ 

エラーがSQL構文エラーとして戻ってくる:バージョン...エラー変形例では

tabl = "Action" 
    query = "SHOW FULL COLUMNS FROM `Action`;" 
    println " "+ query 
    dbConnection.eachRow(query){ 

作業

。あなたが見ることができるように、文は文字通り同一です。私は犯人探ししようとしているだけでGroovyのだと思う

SHOW FULL COLUMNS FROM `Action`; 
    May 20, 2013 10:52:01 AM groovy.sql.Sql eachRow 
    WARNING: Failed to execute: SHOW FULL COLUMNS FROM `?`; because: 
     Parameter index out of range (1 > number of parameters, which is 0). 
    May 20, 2013 10:52:01 AM groovy.sql.Sql eachRow 

出力は、エラー、ステートメントを示しています。私がリテラル文字列をJDBC接続に送るとき、それは 'Action'テーブルのためにうまくいきます。

私は、誰かがエラーを説明して修正を提供したいと考えています。読書人のために

、私は回避策として、このオプションが見つかりました:「+」を使用して、より少ない冗長オプションがあるかもしれませんが

query = "SHOW FULL COLUMNS FROM `"+ tabl.toString() +"`;" 

。私には、$ {tabl}を使うのがうまくいくかのように感じます。事前に

おかげで、

+0

あなたは '使用してみました;'(代わりに二重引用符の単一引用符に注意してください) '$ {TABL} FROM SHOW FULL COLUMNSを'? – dmahapatro

+0

[SQLクエリでDBを動的に設定する]の複製が可能です(http://stackoverflow.com/questions/2267756/dynamically-set-the-db-in-a-sql-query) –

答えて

3

私はこの問題は、あなたが文字列変数を使用するときに、あなたがそれを使用しない場合よりも異なるオブジェクトタイプを生成することだと思います。 1つはString、もう1つはGStringです。

def a = "123" 
def b = "abc"+a 
def c = "abc${a}" 
println b.class 
println c.class 

>> 

class java.lang.String 
class org.codehaus.groovy.runtime.GStringImpl 

eachRow機能が何らかの理由でこの違いに敏感であるようだ。

例えば、このスクリプトと出力を参照してください。

別の回避策はtoStringを呼び出すことであろう..あなたが使用している二つの機能があるhttp://groovy.codehaus.org/api/groovy/sql/Sql.html#eachRow(groovy.lang.GString,%20groovy.lang.Closure)

  • http://groovy.codehaus.org/api/groovy/sql/Sql.html#eachRow(java.lang.String,%20groovy.lang.Closure)
    • しかし、彼らは異なる動作をしたい、なぜ私が見ることができませんquery変数に - それはそれをStringにキャストします:

      def d = c.toString() 
      println d.class 
      
      >> 
      
      class java.lang.String 
      
    3

    私もこれに遭遇しました。回避策はありますが、org.codehaus.groovy.runtime.GStringImplバージョンのtoString()に電話するのがよりクリーンな方法です。つまり、準備された文の機能や実行の保護が必要ない場合です。これは、元の文字列がGStringと表示されるため、Groovy SQLエンジンがプリペアドステートメントに変換しようとしているためです。 SQLインジェクション攻撃を防ぐために、エンドユーザーから提供される可能性のある値を使用する場合は、これを使用することをお勧めします。あなたのケースでは、私の心配ではなかったので、toString()はうまく動作します。

    参照: http://groovy.codehaus.org/Tutorial+6+-+Groovy+SQL

    +0

    これは私がしなければならなかったものです行う。私のeachRowメソッドはGStringを使って私の質問を準備された文にしようとしていました。それは読み取り専用なので、入力はユーザーから来ていないので、私がしなければならなかったのは以下の通りでした: sql.eachRow(query.toString()){// stuff} – Shastings

    関連する問題