5

JDBC SQL クエリでの文字列の使用について質問があります。以下に 2 つの例を示します。両方ともうまくいくと思いますが、うまくいきません。

作業バージョン...

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

エラーバリアント:

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

エラーは SQL 構文エラーとして返されます。ご覧のとおり、ステートメントはテキスト的に同一です。

出力にはステートメントが表示され、次にエラーが表示されます。

   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

それは、Groovy が犯人を探しているだけだと思います。リテラル文字列を JDBC 接続にフィードすると、「アクション」テーブルで問題なく動作します。

誰かがエラーを説明し、修正を提供できることを願っています。

それらの読書のために、私はこのオプションを回避策として見つけました:

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

「+」を使用して、より詳細なオプションがあるかもしれませんが。私には、 ${table} を使用するとうまくいくように感じます。

前もって感謝します、

4

2 に答える 2

4

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

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

于 2013-09-26T16:56:31.067 に答える
3

問題は、文字列内変数を使用すると、使用しない場合とは異なるオブジェクト型が生成されることだと思います。1 つは 、もう 1 つはStringです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何故かこの違いに敏感な機能のようです。使用している2つの関数は

しかし、なぜ彼らが異なる行動をとるのかわかりません..

toString別の回避策は、変数を呼び出すことです。これにより、次queryのようにキャストされますString

def d = c.toString()
println d.class

>>

class java.lang.String
于 2013-07-24T00:14:34.817 に答える