97 votes

Plusieurs requêtes exécutées en Java dans une seule instruction

Bonjour, je me demandais s'il était possible d'exécuter quelque chose comme ceci en utilisant JDBC, car il fournit actuellement une exception, même si cela est possible dans le navigateur de requêtes MySQL.

 "SELECT FROM * TABLE;INSERT INTO TABLE;"
 

Bien que je me rende compte qu'il est possible de scinder la chaîne de requête SQL et d'exécuter l'instruction deux fois, mais je me demandais s'il existait une approche unique pour cela.

     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);
 

133voto

Ravinder Points 12604

Je me demandais si il est possible d'exécuter quelque chose comme ceci à l'aide de JDBC.

"SELECT FROM * TABLE;INSERT INTO TABLE;"

Oui c'est possible. Il y a deux façons de faire, autant que je sache. Ils sont

 1. By setting database connection property to allow multiple queries,
    separated by a semi-colon by default.
 2. By calling a stored procedure that returns cursors implicit.

Les exemples suivants démontrent les deux possibilités.

Exemple 1: ( pour permettre À de multiples requêtes ):

Lors de l'envoi d'une demande de connexion, vous devez ajouter une propriété de connexion allowMultiQueries=true de la base de données d'url. C'est de connexion supplémentaires de la propriété de ces si il existe déjà certains, comme autoReConnect=true, etc.. valeurs Acceptables pour allowMultiQueries propriété sont true, false, yes, et no. Toute autre valeur est rejetée à l'exécution avec un SQLException.

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

À moins qu'une telle instruction est passée, une SQLException est levée.

Vous devez utiliser execute( String sql ) ou de ses autres variantes à extraire les résultats de l'exécution de la requête.

boolean hasMoreResultSets = stmt.execute( multiQuerySqlString );

Pour itérer sur les processus et résultats que vous avez besoin étapes suivantes:

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

Exemple 2: les Étapes à suivre:

  1. Créer une procédure avec un ou plusieurs select, et DML des requêtes.
  2. Appel de java à l'aide d' CallableStatement.
  3. Vous pouvez capturer plusieurs ResultSets exécutée dans la procédure.
    DML résultats ne peuvent pas être capturés, mais peut émettre une autre select
    pour trouver la façon dont les lignes sont affectées dans le tableau.

Exemple de table et de la procédure:

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)

Appel de Procédure à partir de 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

32voto

Himanshu Mohta Points 546

Vous pouvez utiliser la mise à jour par lots, mais les requêtes doivent être des requêtes d'action (c.-à-d. Insérer, mettre à jour et supprimer)

 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();
 

11voto

muye Points 66

D'après mes tests, l'indicateur correct est "allowMultiQueries = true"

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X