web-dev-qa-db-ger.com

Mehrere Abfragen, die in Java in einer einzigen Anweisung ausgeführt werden

Hallo, ich habe mich gefragt, ob es möglich ist, so etwas mit JDBC auszuführen, da es derzeit eine Ausnahme darstellt, obwohl dies im MySQL-Abfragebrowser möglich ist.

"SELECT FROM * TABLE;INSERT INTO TABLE;"

Ich weiß zwar, dass es möglich ist, die SQL-Abfragezeichenfolge aufzuteilen und die Anweisung zweimal auszuführen, aber ich habe mich gefragt, ob es dafür einen einmaligen Ansatz gibt.

    String url = "jdbc:mysql://localhost:3306/";
    String dbName = "databaseinjection";
    String driver = "com.mysql.jdbc.Driver";
    String sqlUsername = "root"; 
    String sqlPassword = "abc";

    Class.forName(driver).newInstance();

    connection = DriverManager.getConnection(url+dbName, sqlUsername, sqlPassword);
81
MilindaD

Ich habe mich gefragt, ob es möglich ist, so etwas mit JDBC auszuführen.

"SELECT FROM * TABLE;INSERT INTO TABLE;"

Ja, es ist möglich. Es gibt zwei Möglichkeiten, soweit ich weiß. Sie sind

  1. Durch Festlegen der Datenbankverbindungseigenschaft zum Zulassen mehrerer Abfragen.... Standardmäßig durch ein Semikolon getrennt.
  2. Durch Aufrufen einer gespeicherten Prozedur, die implizit Cursor zurückgibt.

Die folgenden Beispiele zeigen die beiden oben genannten Möglichkeiten. 

Beispiel 1: (Um mehrere Abfragen zuzulassen): 

Beim Senden einer Verbindungsanforderung müssen Sie eine Verbindungseigenschaft allowMultiQueries=true an die Datenbank-URL anhängen. Dies ist eine zusätzliche Verbindungseigenschaft für diejenigen, die bereits vorhanden sind, wie autoReConnect=true usw. Die zulässigen Werte für die allowMultiQueries-Eigenschaft sind true, false, yes und no. Jeder andere Wert wird zur Laufzeit mit einer SQLException zurückgewiesen. 

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

Wenn eine solche Anweisung nicht übergeben wird, wird eine SQLException ausgegeben.

Sie müssen execute( String sql ) oder seine anderen Varianten verwenden, um Ergebnisse der Abfrageausführung abzurufen. 

boolean hasMoreResultSets = stmt.execute( multiQuerySqlString );

Zum Durchlaufen und Verarbeiten der Ergebnisse sind folgende Schritte erforderlich: 

READING_QUERY_RESULTS: // label  
    while ( hasMoreResultSets || stmt.getUpdateCount() != -1 ) {  
        if ( hasMoreResultSets ) {  
            Resultset rs = stmt.getResultSet();
            // handle your rs here
        } // if has rs
        else { // if ddl/dml/...
            int queryResult = stmt.getUpdateCount();  
            if ( queryResult == -1 ) { // no more queries processed  
                break READING_QUERY_RESULTS;  
            } // no more queries processed  
            // handle success, failure, generated keys, etc here
        } // if ddl/dml/...

        // check to continue in the loop  
        hasMoreResultSets = stmt.getMoreResults();  
    } // while results

Beispiel 2: Schritte, die zu befolgen sind: 

  1. Erstellen Sie eine Prozedur mit einer oder mehreren select- und DML-Abfragen.
  2. Rufen Sie es von Java aus mit CallableStatement auf.
  3. Sie können mehrere ResultSets erfassen, die in einer Prozedur ausgeführt werden.
    DML-Ergebnisse können nicht erfasst werden, können jedoch eine andere select ausgeben.
    , um herauszufinden, wie die Zeilen in der Tabelle betroffen sind. 

Probentabelle und Prozedur

mysql> create table tbl_mq( i int not null auto_increment, name varchar(10), primary key (i) );
Query OK, 0 rows affected (0.16 sec)

mysql> delimiter //
mysql> create procedure multi_query()
    -> begin
    ->  select count(*) as name_count from tbl_mq;
    ->  insert into tbl_mq( names ) values ( 'ravi' );
    ->  select last_insert_id();
    ->  select * from tbl_mq;
    -> end;
    -> //
Query OK, 0 rows affected (0.02 sec)
mysql> delimiter ;
mysql> call multi_query();
+------------+
| name_count |
+------------+
|          0 |
+------------+
1 row in set (0.00 sec)

+------------------+
| last_insert_id() |
+------------------+
|                3 |
+------------------+
1 row in set (0.00 sec)

+---+------+
| i | name |
+---+------+
| 1 | ravi |
+---+------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Aufruf von Java

CallableStatement cstmt = con.prepareCall( "call multi_query()" );  
boolean hasMoreResultSets = cstmt.execute();  
READING_QUERY_RESULTS:  
    while ( hasMoreResultSets ) {  
        Resultset rs = stmt.getResultSet();
        // handle your rs here
    } // while has more rs
122
Ravinder Reddy

Sie können die Stapelaktualisierung verwenden, aber Abfragen müssen Aktionsabfragen (d. H. Einfügen, Aktualisieren und Löschen) sein 

Statement s = c.createStatement();
String s1 = "update emp set name='abc' where salary=984";
String s2 = "insert into emp values ('Osama',1420)";  
s.addBatch(s1);
s.addBatch(s2);     
s.executeBatch();
25
Himanshu Mohta

Hinweis: Wenn Sie über mehrere Verbindungseigenschaften verfügen, trennen Sie diese mit:

&

Um Ihnen etwas zu geben wie:

url="jdbc:mysql://localhost/glyndwr?autoReconnect=true&allowMultiQueries=true"

Ich hoffe das hilft jemandem.

Grüße,

Glyn

14
Glyn

Basierend auf meinen Tests lautet das korrekte Flag "allowMultiQueries = true".

10
muye

Warum versuchst du nicht, einen Stored Procedure dafür zu schreiben?

Sie können den Result Set herausholen und in demselben Stored Procedure können Sie Insert was Sie wollen.

Die einzige Sache ist, dass Sie die neu eingefügten Zeilen im Result Set möglicherweise nicht erhalten, wenn Sie Insert nach der Select eingeben.

2
JHS

Ich denke, dies ist der einfachste Weg für die Mehrfachauswahl/Aktualisierung/Einfügung/Löschung. Sie können beliebig viele Aktualisierungen/Einfügungen/Löschvorgänge ausführen, die Sie nach Auswahl ausführen möchten (Sie müssen zuerst eine Auswahl treffen (ein Dummy, falls erforderlich)) mit executeUpdate (str). und wenn Sie eine neue Auswahl benötigen, schließen Sie 'Anweisung' und 'Verbindung' und machen Sie eine neue Auswahl für die nächste Auswahl. Wie zum Beispiel:

String str1 = "select * from users";
String str9 = "INSERT INTO `port`(device_id, potition, port_type, di_p_pt) VALUE ('"+value1+"', '"+value2+"', '"+value3+"', '"+value4+"')";
String str2 = "Select port_id from port where device_id = '"+value1+"' and potition = '"+value2+"' and port_type = '"+value3+"' ";
try{  
    Class.forName("com.mysql.jdbc.Driver").newInstance();
    theConnection=(Connection) DriverManager.getConnection(dbURL,dbuser,dbpassword);  
    theStatement = theConnection.prepareStatement(str1);
    ResultSet theResult = theStatement.executeQuery();
    int count8 = theStatement.executeUpdate(str9);
    theStatement.close();
    theConnection.close();
    theConnection=DriverManager.getConnection(dbURL,dbuser,dbpassword);
    theStatement = theConnection.prepareStatement(str2);
    theResult = theStatement.executeQuery();

    ArrayList<Port> portList = new ArrayList<Port>();
    while (theResult.next()) {
        Port port = new Port();
        port.setPort_id(theResult.getInt("port_id"));

        portList.add(port);
    }

Ich hoffe, es hilft