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 c'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);
Je me demandais s'il était possible d'exécuter quelque chose comme ceci en utilisant JDBC.
"SELECT FROM * TABLE;INSERT INTO TABLE;"
Oui c'est possible. Il y a deux façons, à ma connaissance. Elles sont
Les exemples suivants illustrent les deux possibilités ci-dessus.
Exemple 1: (Pour autoriser plusieurs requêtes):
Lors de l'envoi d'une demande de connexion, vous devez ajouter une propriété de connexion allowMultiQueries=true
à l'URL de la base de données. Ceci est une propriété de connexion supplémentaire à ceux qui existent déjà, comme autoReConnect=true
, etc. Les valeurs acceptables pour la propriété allowMultiQueries
sont true
, false
, yes
et no
. Toute autre valeur est rejetée à l'exécution avec une variable SQLException
.
String dbUrl = "jdbc:mysql:///test?allowMultiQueries=true";
À moins qu'une telle instruction ne soit transmise, une SQLException
est lancée.
Vous devez utiliser execute( String sql )
ou ses autres variantes pour récupérer les résultats de l'exécution de la requête.
boolean hasMoreResultSets = stmt.execute( multiQuerySqlString );
Pour parcourir et traiter les résultats, vous devez suivre les é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: Étapes à suivre:
select
et DML
.CallableStatement
.ResultSet
s exécutés dans une procédure.select
Exemple de table et de 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)
Procédure d'appel à 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
Vous pouvez utiliser la mise à jour par lots, mais les requêtes doivent être des requêtes d'action (c'est-à-dire 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();
Astuce: Si vous avez plusieurs propriétés de connexion, séparez-les par:
&
Pour vous donner quelque chose comme:
url="jdbc:mysql://localhost/glyndwr?autoReconnect=true&allowMultiQueries=true"
J'espère que ça aidera quelqu'un.
Cordialement,
Glyn
D'après mes tests, l'indicateur correct est "allowMultiQueries = true"
Pourquoi n'essayez-vous pas d'écrire un Stored Procedure
pour cela?
Vous pouvez obtenir le Result Set
et dans le même Stored Procedure
vous pouvez Insert
ce que vous voulez.
La seule chose à faire est que vous pourriez ne pas obtenir les nouvelles lignes insérées dans Result Set
si vous Insert
après la Select
.
Je pense que c'est le moyen le plus simple de sélectionner/mettre à jour/insérer/supprimer plusieurs fois. Vous pouvez exécuter autant de mises à jour/insérer/supprimer que vous le souhaitez après la sélection (vous devez d'abord sélectionner (un mannequin si nécessaire)) avec executeUpdate (str) (utilisez simplement new int (count1, count2, ...)) et si vous avez besoin d'une nouvelle sélection, fermez 'statement' et 'connection' et faites new pour next select. Comme exemple:
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);
}
J'espère que ça aide