code

단일 명령문에서 Java에서 실행되는 여러 쿼리

codestyles 2020. 9. 5. 09:57
반응형

단일 명령문에서 Java에서 실행되는 여러 쿼리


안녕하세요 MySQL 쿼리 브라우저에서 가능하더라도 현재 예외를 제공하므로 JDBC를 사용하여 이와 같은 것을 실행할 수 있는지 궁금합니다.

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

JDBC를 사용하여 이와 같은 것을 실행할 수 있는지 궁금합니다.

"SELECT FROM * TABLE;INSERT INTO TABLE;"

네 가능합니다. 내가 아는 한 두 가지 방법이 있습니다. 그들은

  1. 기본적으로 세미콜론으로 구분 된 여러 쿼리를 허용하도록 데이터베이스 연결 속성을 설정합니다.
  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 : 따라야 할 단계 :

  1. 하나 이상의 selectDML쿼리를 사용 하여 프로 시저를 만듭니다 .
  2. 을 사용하여 Java에서 호출하십시오 CallableStatement.
  3. You can capture multiple ResultSets executed in procedure.
    DML results can't be captured but can issue another select
    to find how the rows are affected in the table.

Sample table and procedure:

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)

Call Procedure from 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

You can use Batch update but queries must be action(i.e. insert,update and delete) queries

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

Hint: If you have more than one connection property then separate them with:

&

To give you somthing like:

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

I hope this helps some one.

Regards,

Glyn


Based on my testing, the correct flag is "allowMultiQueries=true"


Why dont you try and write a Stored Procedure for this?

You can get the Result Set out and in the same Stored Procedure you can Insert what you want.

The only thing is you might not get the newly inserted rows in the Result Set if you Insert after the Select.


I think this is the easiest way for multy selection/update/insert/delete. You can run as many update/insert/delete as u want after select (you have to make a select first(a dummy if needed)) with executeUpdate(str) (just use new int(count1,count2,...)) and if u need a new selection close 'statement' and 'connection' and make new for next select. Like example:

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

I hope it helps

참고URL : https://stackoverflow.com/questions/10797794/multiple-queries-executed-in-java-in-single-statement

반응형