Câu hỏi Nhiều truy vấn được thực hiện bằng java trong một câu lệnh


Chào Tôi đã tự hỏi nếu nó có thể thực hiện một cái gì đó như thế này bằng cách sử dụng JDBC vì nó hiện đang cung cấp một ngoại lệ mặc dù nó có thể trong trình duyệt truy vấn MySQL.

"SELECT FROM * TABLE;INSERT INTO TABLE;"

Trong khi tôi nhận ra rằng có thể có chuỗi truy vấn SQL bị chia nhỏ và câu lệnh được thực hiện hai lần nhưng tôi đã tự hỏi liệu có cách tiếp cận một lần cho điều này hay không.

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

76
2018-05-29 10:58


gốc


đưa vào một thủ tục được lưu trữ, gọi thủ tục được lưu trữ. có nghĩa là bạn cũng không phải triển khai lại mã của mình khi bạn muốn thực hiện thay đổi. - Chris
Có một thuộc tính mà bạn phải đặt trong chuỗi kết nối allowMultiQueries=true. - Rahul
sao chép có thể xảy ra: Làm thế nào để thực hiện các truy vấn sql tổng hợp trong java? [1] [1]: stackoverflow.com/questions/6773393/… - prayagupd
Hi Rahul, cho dự án này tôi đang sử dụng một đối tượng kết nối đồng bằng cũ và bạn có biết nơi tôi nên đặt "allowMultiQueries = true". Đã thêm mã đối tượng kết nối trong câu hỏi - MilindaD


Các câu trả lời:


Tôi đã tự hỏi nếu nó có thể thực hiện một cái gì đó như thế này bằng cách sử dụng JDBC.

"SELECT FROM * TABLE;INSERT INTO TABLE;"

Có, điều đó là có thể. Có hai cách, theo như tôi biết. họ đang

  1. Bằng cách đặt thuộc tính kết nối cơ sở dữ liệu để cho phép nhiều truy vấn, được phân tách bằng dấu chấm phẩy theo mặc định.
  2. Bằng cách gọi một thủ tục lưu sẵn trả về con trỏ ngầm.

Các ví dụ sau minh họa hai khả năng trên.

ví dụ 1: (Để cho phép nhiều truy vấn):

Trong khi gửi yêu cầu kết nối, bạn cần phải thêm thuộc tính kết nối allowMultiQueries=true vào url cơ sở dữ liệu. Đây là thuộc tính kết nối bổ sung cho những người đã tồn tại một số, như autoReConnect=true, vv .. Giá trị được chấp nhận cho allowMultiQueries tài sản là true, false, yesno. Bất kỳ giá trị nào khác bị từ chối khi chạy với một SQLException.

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

Trừ khi lệnh đó được thông qua, một SQLException được ném.

Bạn phải sử dụng execute( String sql ) hoặc các biến thể khác của nó để tìm nạp kết quả thực hiện truy vấn.

boolean hasMoreResultSets = stmt.execute( multiQuerySqlString );

Để lặp qua và xử lý kết quả, bạn cần các bước sau:

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

Ví dụ 2: Các bước để làm theo:

  1. Tạo một thủ tục với một hoặc nhiều selectDML truy vấn.
  2. Gọi nó từ java bằng cách sử dụng CallableStatement.
  3. Bạn có thể chụp nhiều ResultSets thực hiện trong thủ tục.
    Không thể chụp kết quả DML nhưng có thể tạo kết quả khác select
    để tìm cách các hàng bị ảnh hưởng trong bảng.

Bảng mẫu và thủ tục:

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)

Thủ tục gọi từ 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

108
2018-05-29 18:33



Thật không may, điều này không hoạt động với phiên bản Derby được nhúng. - user2428118
@ user2428118: Lý do? Có lỗi nào không? Bạn có kiểm tra xem Driver có hỗ trợ tính năng này không? - Ravinder Reddy
tôi đã thêm allowMultiQueries = true và hoạt động tốt :) - Hazim
Cảm ơn bạn @RavinderReddy - shiva R


Bạn có thể sử dụng Cập nhật hàng loạt nhưng truy vấn phải là hành động (ví dụ: chèn, cập nhật và xóa) truy vấn

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

22
2018-05-29 11:46



Bạn không thể sử dụng phương pháp này cho "truy vấn sprocname gọi ('abc', 984)"? - sebnukem


Gợi ý: Nếu bạn có nhiều hơn một thuộc tính kết nối, sau đó tách chúng với:

&

Để cung cấp cho bạn mọi thứ như:

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

Tôi hi vọng điêu nay se giup được ai đo.

Trân trọng,

Glyn


12
2018-01-25 23:30





Dựa trên thử nghiệm của tôi, cờ chính xác là "allowMultiQueries = true"


7
2017-11-08 07:18





Tại sao bạn không thử và viết Stored Procedure cho điều này?

Bạn có thể lấy Result Set ra và trong cùng Stored Procedure bạn có thể Insert bạn muốn gì.

Điều duy nhất là bạn có thể không nhận được các hàng mới được chèn vào Result Set nếu bạn Insert sau Select.


0
2018-05-29 11:04





Tôi nghĩ đây là cách dễ nhất để chọn nhiều / cập nhật / chèn / xóa. Bạn có thể chạy bao nhiêu update / insert / delete như u muốn sau khi chọn (bạn phải chọn trước (dummy nếu cần)) với executeUpdate (str) (chỉ cần dùng int mới (count1, count2, ...)) và nếu u cần một lựa chọn mới gần 'tuyên bố' và 'kết nối' và làm cho mới để lựa chọn tiếp theo. Ví dụ:

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

Tôi hy vọng nó sẽ giúp


-1
2018-06-28 10:28



Việc mở kết nối DB rất tốn kém. Không phải là một thực hành tốt làm điều đó mọi lúc. Cái mà bạn đã đưa ra sẽ làm cho số lượt truy cập DB số cho số lượng truy vấn n dẫn đến hiệu suất kém. - Arun Kumar Mudraboyina