こんにちは、JDBCを使用してこのようなものを実行できるかどうか疑問に思っていました。MySQLクエリブラウザでは可能ですが、現在例外を提供しています。
"SELECT FROM * TABLE;INSERT INTO TABLE;"
SQLクエリ文字列を分割し、ステートメントを2回実行することで可能になることはわかっていますが、これには1回限りのアプローチがあるのではないかと考えていました。
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);
JDBCを使用してこのような何かを実行できるかどうか疑問に思っていました。
"SELECT FROM * TABLE;INSERT INTO TABLE;"
はい、可能です。私の知る限り、2つの方法があります。彼らです
次の例は、上記の2つの可能性を示しています。
例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
クエリを含むプロシージャを作成します。CallableStatement
を使用して呼び出します。ResultSet
sをキャプチャできます。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"
これが役に立つことを願っています。
よろしく、
グリン
私のテストに基づいて、正しいフラグは「allowMultiQueries = true」です
このためにStored Procedure
を書いてみませんか?
Result Set
を取得し、同じStored Procedure
でInsert
を取得できます。
唯一のことは、Insert
の後にSelect
がある場合、Result Set
に新しく挿入された行を取得できない可能性があることです。
これが複数選択/更新/挿入/削除の最も簡単な方法だと思います。選択後に必要なだけ更新/挿入/削除を実行できます(必要に応じて最初に選択する必要があります(必要に応じてダミーを作成する必要があります))executeUpdate(str)(ちょうど新しいint(count1、count2、...)を使用します)新しい選択が必要な場合は、「statement」と「connection」を閉じて、次の選択のために新しいものを作成します。例のように:
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);
}
私はそれが役立つことを願っています