2013-05-20 13 views
5

Ho una domanda sull'utilizzo di una stringa in una query SQL JDBC. Ecco due esempi e mi aspetto che funzionino entrambi, ma non lo fanno.

versione funzionante ...

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

In variante di errore:

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

L'errore ritorna come un errore di sintassi SQL. Come puoi vedere le dichiarazioni sono testualmente identiche.

L'uscita mostrano la dichiarazione, poi un errore:

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 

penso che è solo Groovy cercando di cercare un colpevole. Quando inserisco la stringa letterale nella connessione JDBC funziona perfettamente per la tabella 'Action'.

Spero che qualcuno possa spiegare l'errore e offrire una soluzione.

per chi legge, ho trovato questa opzione come una soluzione :

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

Mentre ci potrebbe essere un'opzione meno prolissa, l'utilizzo di "+"; a me sembra che usare $ {tabl} dovrebbe funzionare.

Grazie in anticipo,

+0

Hai provato a usare ' 'colonne completi MOSTRA DA $ {} tabl;'' (notare l'apostrofo invece di doppie virgolette)? – dmahapatro

+0

possibile duplicato di [impostare dinamicamente il db in una query SQL] (http://stackoverflow.com/questions/2267756/dynamically-set-the-db-in-a-sql-query) –

risposta

3

Credo che il problema è che quando si utilizza la variabile in stringa produce un tipo di oggetto diverso rispetto a quando non lo usate. Uno è un String, l'altro uno GString.

esempio vedere questo script e l'uscita:

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 

Sembra che la funzione eachRow è sensibile a questa differenza, per qualche motivo. Le due funzioni che si sta utilizzando sono

ma non riesco a capire perché avevano comportano in modo diverso ..

Un'altra soluzione potrebbe essere quella di chiamare toString sulla variabile query - che la ritrasmetterà a String:

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

>> 

class java.lang.String 
3

Mi sono imbattuto anche in questo. La tua soluzione funziona, ma un modo più semplice sarebbe chiamare toString() nella versione org.codehaus.groovy.runtime.GStringImpl. Cioè, se non hai bisogno di nessuna delle caratteristiche dell'istruzione preparate o della protezione sull'esecuzione. Ciò è dovuto al motore SQL di Groovy che tenta di trasformarlo in un'istruzione preparata, poiché vede la stringa originale come GString. Al fine di prevenire attacchi di SQL injection, si vorrebbe questo però quando si utilizzano valori che potrebbero essere forniti dall'utente finale. Nel tuo caso e il mio non era un problema quindi toString() funziona bene.

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

+0

Questo è quello che ho dovuto fare. Il mio metodo eachRow utilizzava il GString per provare a trasformare la mia query in una dichiarazione preparata. Poiché è di sola lettura e l'input non proviene dall'utente, tutto ciò che dovevo fare era: sql.eachRow (query.toString()) {// stuff} – Shastings