2009-07-02 32 views
13

Trong SQL Server, bạn có thể làm những việc như thế này:Có một Oracle tương đương với SQL Server's OUTPUT INSERTED. *?

INSERT INTO some_table (...) OUTPUT INSERTED.* 
VALUES (...) 

Vì vậy, bạn có thể chèn bộ tùy ý các cột/giá trị và có được những kết quả trở lại. Có cách nào để làm điều này trong Oracle?

Điều tốt nhất tôi có thể đưa ra là thế này:

INSERT INTO some_table (...) 
VALUES (...) 
RETURNING ROWID INTO :out_rowid 

... sử dụng: out_rowid như là một biến ràng buộc. Và sau đó sử dụng truy vấn thứ hai như sau:

SELECT * 
FROM some_table 
WHERE ROWID = :rowid 

... nhưng điều này không hoàn toàn giống như trả về mọi thứ trong cột, không chỉ các cột tôi đã chèn.

Có cách nào tốt hơn để làm điều này mà không cần sử dụng nhiều PL/SQL và tốt nhất là chỉ với một truy vấn?

+1

Nếu đó là các cột bạn quan tâm (không phải là dữ liệu hàng) ... - Làm thế nào bạn có được (...)? Chắc chắn vào thời điểm đó bạn biết cột nào đang được tham chiếu trong chèn? –

+0

Tôi chỉ đọc trên OUTPUT INSERTED (http://msdn.microsoft.com/en-us/library/ms177564.aspx). Dường như nó cho phép bạn chọn xem dữ liệu hàng trả về là trước hoặc sau khi bất kỳ trình kích hoạt bảng nào đã chạy. Mệnh đề RETURNING của Oracle không hỗ trợ điều này - nó chỉ cung cấp cho bạn dữ liệu sau khi các trình kích hoạt đã có cơ hội thay đổi nó. –

+0

@ Jeffrey Kemp - Tôi sẽ biết những cột đó là gì. Tuy nhiên, cơ sở dữ liệu nên. :-) –

Trả lời

3

Điều khoản RETURNING hỗ trợ BULK COLLECT INTO tổng hợp. Xem xét (10g):

SQL> CREATE TABLE t (ID NUMBER); 

Table created 
SQL> INSERT INTO t (SELECT ROWNUM FROM dual CONNECT BY LEVEL <= 5); 

5 rows inserted 
SQL> DECLARE 
    2  TYPE tab_rowid IS TABLE OF ROWID; 
    3  l_r tab_rowid; 
    4 BEGIN 
    5  UPDATE t SET ID = ID * 2 
    6  RETURNING ROWID BULK COLLECT INTO l_r; 
    7  FOR i IN 1 .. l_r.count LOOP 
    8  dbms_output.put_line(l_r(i)); 
    9  END LOOP; 
10 END; 
11/

AADcriAALAAAAdgAAA 
AADcriAALAAAAdgAAB 
AADcriAALAAAAdgAAC 
AADcriAALAAAAdgAAD 
AADcriAALAAAAdgAAE 

Nó hoạt động với nhiều hàng UPDATEDELETE với phiên bản của tôi (10.2.0.3.0) nhưng KHÔNG với INSERT:

SQL> DECLARE 
    2  TYPE tab_rowid IS TABLE OF ROWID; 
    3  l_r tab_rowid; 
    4 BEGIN 
    5  INSERT INTO t (SELECT ROWNUM FROM dual CONNECT BY LEVEL <= 5) 
    6  RETURNING ROWID BULK COLLECT INTO l_r; 
    7  FOR i IN 1 .. l_r.count LOOP 
    8  dbms_output.put_line(l_r(i)); 
    9  END LOOP; 
10 END; 
11/

ORA-06550: line 7, column 5: 
PL/SQL: ORA-00933: SQL command not properly ended 

Có thể bạn có một hơn phiên bản gần đây (11g?) và BULK COLLECT INTO được hỗ trợ cho nhiều hàng INSERT giây?

+0

Tôi không quá lo lắng về số hàng vì tôi là số cột. Số lượng hàng sẽ khá nhiều luôn luôn là một trong khi các cột sẽ được biến. –

+0

@ Jason: Tôi nghĩ rằng bạn sẽ phải sử dụng dbms_sql nếu số cột là biến/không biết tại thời gian biên dịch –

5

Có lẽ tôi không hiểu câu hỏi, nhưng điều này sẽ không làm điều đó? (Bạn phải biết những gì bạn muốn trở lại)

INSERT INTO some_table (...) 
VALUES (...) 
RETURNING some_column_a, some_column_b, some_column_c, ... INTO :out_a, :out_b, :out_c, ... 

@Vincent trở về với số lượng lớn thu vào cho chèn nhiều hàng chỉ hoạt động kết hợp với forall (hay nói cách khác nếu bạn chèn từ bộ sưu tập bạn có thể lấy "kết quả" vào một)

Các vấn đề liên quan