2012-12-13 38 views
5

Tôi có một bảng gọi là sự kiện và tạo một bảng tạm thời khác tmp_event với cùng cột và định nghĩa với sự kiện. Có thể chèn các bản ghi trong sự kiện vào tmp_event bằng cách sử dụng này không?Oracle: Chèn dữ liệu kiểu hàng vào một bảng khác

DECLARE 
    v_record event%rowtype; 
BEGIN 
    Insert into tmp_event values v_record; 
END; 

Có quá nhiều cột trong bảng sự kiện, tôi muốn thử điều này vì tôi không muốn liệt kê tất cả các cột.

Hãy quên đề cập: Tôi sẽ sử dụng tính năng này trong trình kích hoạt, v_record này có thể là đối tượng : new sau khi chèn vào bảng EVENT không?

+0

đã cập nhật câu trả lời bằng cách sử dụng trong 'trigger'. – Annjawn

+0

Tôi đã trả lời về câu hỏi tương tự ở đây: [http://stackoverflow.com/a/26343423/2235483][1] [1]: http://stackoverflow.com/a/26343423/2235483 – Rusty

Trả lời

17

Để chèn một row-

DECLARE 
    v_record event%rowtype; 
BEGIN 
    SELECT * INTO v_record from event where rownum=1; --or whatever where clause 
    Insert into tmp_event values v_record; 
END; 

Hoặc một phiên bản phức tạp hơn để chèn tất cả các hàng từ event -

DECLARE 
    TYPE t_bulk_collect_test_tab IS TABLE OF event%ROWTYPE; 

    l_tab t_bulk_collect_test_tab; 

    CURSOR c_data IS 
    SELECT * 
    FROM event; 
BEGIN 
    OPEN c_data; 
    LOOP 
    FETCH c_data 
    BULK COLLECT INTO l_tab LIMIT 10000; 
    EXIT WHEN l_tab.count = 0; 

    -- Process contents of collection here. 
    Insert into tmp_event values v_record; 
    END LOOP; 
    CLOSE c_data; 
END; 
/

Trong một cò, có nó là có thể nhưng nó giống như con gà hay trứng. Bạn phải khởi tạo tất cả các lĩnh vực của rowtype với các giá trị cột :new như-

v_record.col1 := :new.col1; 
v_record.col2 := :new.col2; 
v_record.col3 := :new.col3; 
.... 

Rõ ràng, các ví dụ PLSQL trên có thể không được sử dụng trong một kích hoạt vì nó sẽ ném một lỗi kích hoạt đột biến. Và không có cách nào khác để bạn có được toàn bộ hàng trong kích hoạt khác ngoài việc truy cập từng cột riêng biệt như tôi giải thích ở trên, vì vậy nếu bạn làm tất cả điều này tại sao không trực tiếp sử dụng :new.col trong chính mình INSERT into temp_event, sẽ giúp bạn tiết kiệm rất nhiều công việc .


Cũng kể từ khi bạn nói đó là rất nhiều công việc để đề cập đến tất cả các cột, (trong Oracle 11gR2) đây là một cách nhanh chóng để làm điều đó bằng cách tạo ra các tuyên bố INSERT và thực hiện nó tự động (mặc dù chưa được thử nghiệm cho hiệu suất).

CREATE OR REPLACE TRIGGER event_air --air stands for "after insert of row" 
AFTER INSERT ON EVENT 
FOR EACH ROW 
    L_query varchar2(2000); --size it appropriately 
BEGIN 

    SELECT 'INSERT INTO tmp_event VALUES ('|| listagg (':new.'||column_name, ',') 
              WITHIN GROUP (ORDER BY column_name) ||')' 
    INTO l_query 
    FROM all_tab_columns 
    WHERE table_name='EVENT'; 

    EXECUTE IMMEDIATE l_query; 

EXCEPTION 
    WHEN OTHERS THEN 
     --Meaningful exception handling here 
END; 
+0

Tôi lưu trữ dữ liệu vào bảng tmp_event là để tránh lỗi kích hoạt. Tôi cập nhật hoặc chèn vào bảng sự kiện, và cũng có thể thêm bản ghi mới vào bảng tmp_event, sau đó truy cập vào nội dung trong tmp_table, điều này có hoạt động không? – Frank

+0

Có nó sẽ. Miễn là bạn không 'chọn' từ bảng nơi kích hoạt, nó sẽ không ném lỗi kích hoạt ngắt. – Annjawn

+0

@LucM Tính năng gì? 'Mutating Trigger' là một lỗi áp dụng cho tất cả các phiên bản của cơ sở dữ liệu Oracle. – Annjawn

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