2013-08-29 7 views
5

Il mio driver jdbc per mysql db è della versione 5.1.25.Posso eseguire più query separate da punto e virgola con MySQL Connector/J?

voglio per eseguire query SQL in questo modo:

statement.execute("select fullName from user where user_id=1; select fullName from user where user_id=2"); 

E ho sempre ricevere un'eccezione:

Exception in thread "main" com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'select fullName from user where user_id=2' at line 1 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) 
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 
    at java.lang.reflect.Constructor.newInstance(Constructor.java:525) 
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:411) 
    at com.mysql.jdbc.Util.getInstance(Util.java:386) 
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1054) 
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4187) 
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4119) 
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2570) 
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2731) 
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2809) 
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2758) 
    at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:894) 
    at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:732) 
    at dbViewer.model.UserConnectionManager.retrieveRoutinesNames1(UserConnectionManager.java:622) 
    at dbViewer.model.UserConnectionManager.main(UserConnectionManager.java:637) 

MA quando ho eseguito questo stessa query (separati da virgola) da linea di comando funziona perfettamente e genera due tabelle come previsto.

+0

Probabilmente no - SQL sarebbe tornato due set di risultati, ciò che sta per essere restituito da execute()? Presumibilmente funziona tutto bene se hai una sola affermazione? – DaveRlz

+0

L'eliminazione di più istruzioni in una query è anche una protezione di sicurezza, sebbene non perfetta. Se è possibile eseguire più query, l'iniezione potrebbe consentire a un intruso di eseguire SQL completamente arbitrario: http://xkcd.com/327. Si dovrebbe fare 'selezionare fullName dall'utente WHERE user_id = 1 O user_id = 2'. È inoltre necessario utilizzare dichiarazioni preparate, per l'efficienza e la sicurezza contro l'iniezione SQL. – yshavit

risposta

1

No, non è possibile. Cosa ti aspetti di ottenere chiamando statement.execute (...)? Restituisce un ResultSet (... che significa una tabella).

È possibile chiamare "select fullName dall'utente in cui user_id in (1, 2)" per ripristinare entrambi i risultati.

Il punto e virgola nelle istruzioni JDBC è molto soggetto a errori in generale. Alcuni driver JDBC non supportano questo (ad esempio, il driver JDBC di IBM per DB2 10.x genera un'eccezione se si chiude l'istruzione SQL con ";").

9

L'utilizzo di ; in una query per la maggior parte dei database non funziona poiché di solito non fa parte della sintassi dell'istruzione stessa, ma un terminatore per riga di comando o input di script per istruzioni separate. La riga di comando o il processore di script vedono un punto e virgola come segnale che l'istruzione è completa e può essere inviata al server.

Anche in JDBC un unico prospetto preparare (o eseguire) dovrebbe essere solo uno dichiarazione reale in modo più istruzioni non sono ammessi e quindi non c'è alcuna necessità di avere un punto e virgola, e per quanto riguarda alcuni (la maggior parte?) database il punto e virgola non fa parte della sintassi dell'istruzione, è semplicemente un errore di sintassi per averne uno incluso.

Se si desidera eseguire più istruzioni, è necessario utilizzare esecuzioni separate. Tecnicamente, MySQL ha un'opzione per supportare più esecuzioni che possono essere abilitate da una proprietà di connessione. Questo comportamento non è conforme alle specifiche/API JDBC e rende il tuo codice meno portabile. Vedere allowMultiQueries su Driver/Datasource Class Names, URL Syntax and Configuration Properties for Connector/J

8

voglio per eseguire query SQL in questo modo:

statement.execute("select fullName from user where user_id=1; select fullName from user where user_id=2");

Questo è possibile solo se è stata impostata proprietà di connessione un database per consentire a più query per eseguire tutto in una volta. E il nome della proprietà è allowMultiQueries=true. Questa proprietà deve essere impostata e inviare insieme al server una richiesta di connessione al database. sintassi generale è simile a questo:

String dbUrl = "jdbc:mysql:///test?allowMultiQueries=true"; 

Questa è proprietà di connessione ad aggiungersi a quelli già esiste se alcuni, come autoReConnect=true, ecc

valori accettabili per allowMultiQueries proprietà sono true, false, yes e no. Qualsiasi altro valore viene rifiutato in fase di esecuzione con un SQLException.

È necessario utilizzare execute(String sql) o le sue altre varianti per recuperare i risultati dell'esecuzione della query.

multiQuerySqlString = "select fullName from user where user_id=1; "; 
multiQuerySqlString += "select fullName from user where user_id=2; "; 
// you can multiple types of result sets 
multiQuerySqlString += "select last_login from user_logs where user_id=1; "; 

boolean hasMoreResultSets = stmt.execute(multiQuerySqlString); 

per scorrere e il processo di risultati richiesti seguenti operazioni:

int rsNumber = 0; 
while (hasMoreResultSets) { 
    rsNumber += 1; 
    Resultset rs = stmt.getResultSet(); 

    // based on the structure of the result set, 
    // you can handle column values. 
    if (rsNumber == 1) { 
     while(rs.next()) { 
      // handle your rs here 
     } // while rs 
    } // if rs is 1 
    else if (rsNumber == 2) { 
     // call a method using this rs. 
     processMyResultSet(rs); // example 
    } // if rs is 2 
    // ... etc 

    // check whether there exist more result sets 
    hasMoreResultSets = stmt.getMoreResults(); 
} // while results 

Fare riferimento a:

Problemi correlati