2013-05-20 11 views
5

Ich habe eine Frage zu einer Zeichenfolge in einer JDBC-SQL-Abfrage verwenden. Hier sind zwei Beispiele und ich erwarte, dass beide funktionieren, aber sie nicht.

Arbeits Version ...

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

In Fehler Variante:

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

Der Fehler kommt zurück als SQL-Syntax-Fehler. Wie Sie sehen können, sind die Aussagen textuell identisch.

Der Ausgang zeigen die Aussage, dann ein Fehler:

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 

Ich denke, dass gerade Groovy ist nach einem Schuldigen zu suchen versuchen. Wenn ich die Literal-Zeichenfolge an die JDBC-Verbindung füttere, funktioniert sie für die Tabelle 'Aktion' einwandfrei.

Ich hoffe jemand den Fehler erklären kann, und ein Update anbieten.

Für diejenigen, Lesen, fand ich diese Option als Abhilfe:

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

Zwar gibt es eine weniger ausführliche Option sein, mit "+"; Für mich fühlt es sich an, als ob die Verwendung von $ {tabl} funktionieren sollte.

Vielen Dank im Voraus,

+0

Haben Sie versucht, mit ' 'SHOW FULL COLUMNS FROM $ {Tabl};'' (man beachte den Apostroph statt doppelte Anführungszeichen)? – dmahapatro

+0

möglich Duplikat von [dynamisch die Datenbank in einer SQL-Abfrage setzen] (http://stackoverflow.com/questions/2267756/dynamically-set-the-db-in-a-sql-query) –

Antwort

3

denke ich das Problem, dass, wenn Sie das in-String-Variable verwenden, um einen anderen Objekttyp als erzeugt, wenn Sie ihn nicht verwenden. Einer ist ein String, der andere ein GString.

siehe zum Beispiel das Skript und die Ausgabe:

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 

Es scheint, dass die eachRow Funktion dieser Differenz aus irgendeinem Grund empfindlich ist. Die beiden Funktionen Sie verwenden sind

Aber ich kann nicht sehen, warum sie sich anders verhalten würde ..

Eine andere Lösung toString zu nennen wäre auf der query Variable - das wird es zurück werfen auf String:

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

>> 

class java.lang.String 
3

Ich lief auch in diesem. Ihr Workaround funktioniert, aber ein saubererer Weg wäre, toString() auf der org.codehaus.groovy.runtime.GStringImpl-Version aufzurufen. Das heißt, wenn Sie keine der vorbereiteten Anweisungsfunktionen oder den Schutz für die Ausführung benötigen. Dies liegt daran, dass die Groovy-SQL-Engine versucht, sie in eine vorbereitete Anweisung umzuwandeln, da sie die ursprüngliche Zeichenfolge als GString sieht. Um SQL Injection-Angriffe zu verhindern, möchten Sie dies jedoch, wenn Sie Werte verwenden, die vom Endbenutzer bereitgestellt werden können. In Ihrem Fall und meins war das kein Problem, also toString() funktioniert gut.

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

+0

Dies ist, was ich musste machen. Meine eachRow-Methode verwendete den GString, um meine Abfrage in eine vorbereitete Anweisung umzuwandeln. Da es schreibgeschützt ist und die Eingabe nicht vom Benutzer kommt, war alles, was ich tun musste: sql.eachRow (query.toString()) {// stuff} – Shastings