Несколько запросов, выполняемых на 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);
6 ответов:
мне было интересно, можно ли выполнить что-то подобное с помощью JDBC.
"SELECT FROM * TABLE;INSERT INTO TABLE;"
Да, это возможно. Насколько я знаю, есть два пути. Они
- установив свойство подключения к базе данных, чтобы разрешить несколько запросов, по умолчанию разделяется точкой с запятой.
- вызывая хранимую процедуру, которая возвращает неявные курсоры.
следующие примеры демонстрируют выше два возможности.
Пример 1: ( разрешить несколько запросов ):
при отправке запроса на подключение необходимо добавить свойство подключения
allowMultiQueries=true
к url базы данных. Это дополнительное свойство подключения к тем, если уже существует некоторые, какautoReConnect=true
и т. д.. Допустимые значения дляallowMultiQueries
недвижимостьtrue
,false
,yes
иno
. Любое другое значение отклоняется во время выполнения с помощью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: шаги, чтобы следовать:
- создайте процедуру с одним или несколькими
select
иDML
запросы.- вызовите его из java с помощью
CallableStatement
.- вы можете захватить несколько
ResultSet
s выполняется в процедуре.
Результаты 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
вы можете использовать пакетное обновление, но запросы должны быть действия (т. е. вставить,обновить и удалить) запросы
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();
подсказка: если у вас есть несколько свойств соединения, разделите их с помощью:
&
чтобы дать вам что-то вроде:
url="jdbc:mysql://localhost/glyndwr?autoReconnect=true&allowMultiQueries=true"
Я надеюсь, что это помогает кто-то.
С уважением,
глина
почему бы вам не попробовать и написать
Stored Procedure
для этого?вы можете узнать
Result Set
наружу и в то же самоеStored Procedure
вы можетеInsert
то, что вы хотите.единственное, что вы не можете получить вновь вставленные строки в
Result Set
Если выInsert
послеSelect
.
Я думаю, что это самый простой способ для множественного выбора/обновления/вставки/удаления. Вы можете запустить столько update / insert / delete,сколько хотите после выбора (вы должны сначала выбрать(манекен, если необходимо)) с executeUpdate(str) (просто используйте new int(count1, count2,...)) и если вам нужен новый выбор, закройте "оператор" и "соединение" и сделайте новый для следующего выбора. Например:
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); }
надеюсь, это поможет