在单个语句中执行 Java 中的多个查询

嗨,我想知道是否有可能使用 JDBC 执行这样的操作,因为它目前提供了一个异常,即使在 MySQL 查询浏览器中也是可能的。

"SELECT FROM * TABLE;INSERT INTO TABLE;"

虽然我确实意识到,这是可能的 SQL 查询字符串被拆分和语句执行两次,但我想知道是否有一个一次性的方法。

    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);
221612 次浏览

你为什么不试着写一个 Stored Procedure呢?

你可以得到的 Result Set和在相同的 Stored Procedure你可以 Insert你想要的。

唯一的问题是,如果 Insert位于 Select之后,则可能无法在 Result Set中获得新插入的行。

您可以使用批量更新,但查询必须是操作(即插入、更新和删除)查询

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

我想知道是否有可能使用 JDBC 执行类似的操作。

"SELECT FROM * TABLE;INSERT INTO TABLE;"

是的,有可能。据我所知,有两种方法。它们是

  1. 通过将数据库连接属性设置为允许多个查询, separated by a semi-colon by default.
  2. 通过调用隐式返回游标的存储过程。

下面的例子说明了上述两种可能性。

示例1 : (允许多个查询) :

在发送连接请求时,需要将连接属性 allowMultiQueries=true附加到数据库 URL。这是额外的连接属性,如果已经存在一些,如 autoReConnect=true等..。allowMultiQueries属性的可接受值是 truefalseyesno。使用 SQLException在运行时拒绝任何其他值。

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

除非传递这样的指令,否则将抛出 SQLException

您必须使用 execute( String sql )或其他变体来获取查询执行的结果。

boolean hasMoreResultSets = stmt.execute( multiQuerySqlString );

要遍历和处理结果,您需要以下步骤:

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

示例2 : 步骤:

  1. 创建具有一个或多个 selectDML查询的过程。
  2. Call it from java using CallableStatement.
  3. 可以捕获在过程中执行的多个 ResultSet
    不能捕获 DML 结果,但可以发出另一个 select
    查找表中的行受到的影响。

样本表及程序 :

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)

来自 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

根据我的测试,正确的标志是“ allowMultiQuery = true”

提示: 如果您有多个连接属性,那么使用以下方法分隔它们:

&

给你这样的东西:

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

我希望这对某人有帮助。

问候,

格林

我认为这是多重选择/更新/插入/删除的最简单方法。在 select 之后,你可以运行任意数量的 update/insert/delete (你必须先做一个 select (如果需要的话,是一个虚拟的)) ,使用 ExecuteUpdate (str)(只需要使用 new int (count 1,count 2,...)) ,如果你需要一个新的选择,关闭“语句”和“连接”,为下一个 select 创建 new。举个例子:

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

希望能有所帮助