2012-12-13 16 views
5

Mam jedną tabelę o nazwie wydarzenie i stworzył kolejną globalną temp tabeli tmp_event z tych samych kolumn i definicji z imprezy. Czy jest możliwe wstawienie rekordów w zdarzeniu do tmp_event przy użyciu tego?Oracle: Wstawianie danych rowtype do innej tabeli

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

Jest zbyt wiele kolumn w tabeli zdarzeń, chcę spróbować, ponieważ nie chcę wyświetlić wszystkich kolumn.

Nie zapomnij wspomnieć: użyję tego w wyzwalaczu, czy ten v_record może być obiektem : nowy po wstawieniu na stole EVENT?

+0

zaktualizował odpowiedź używając "wyzwalacza". – Annjawn

+0

Mam odpowiedział na podobne pytanie tutaj: [http://stackoverflow.com/a/26343423/2235483][1] [1]: http://stackoverflow.com/a/26343423/2235483 – Rusty

Odpowiedz

17

Aby wstawić jeden 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; 

lub bardziej skomplikowaną wersję wstawić wszystkie wiersze z 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; 
/

w wyzwalacz, tak, to jest możliwe, ale jego jak kura czy jajko. Trzeba zainicjować każde pole z rowtype z wartościami kolumn :new jak-

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

Najwyraźniej przykłady PLSQL powyżej nie mogą być wykorzystane w wyzwalacz ponieważ byłoby wyrzucić błąd wyzwalania mutacja. I nie ma innego sposobu, aby uzyskać cały wiersz w wyzwalaczu, inny niż dostęp do każdej kolumny osobno, jak wyjaśnię powyżej, więc jeśli zrobisz to wszystko, to nie używaj bezpośrednio :new.col w samym sobie, zaoszczędzi ci to dużo pracy .


Ponadto, ponieważ można powiedzieć, że jest to dużo pracy, aby wymienić wszystkie kolumny (w Oracle 11gR2) Oto szybki sposób na osiągnięcie tego poprzez generowanie oświadczenie INSERT i wykonywanie go dynamicznie (choć nie testowano na wydajność).

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

Przechowuję dane w tabeli tmp_event, aby uniknąć mutowania błędu wyzwalacza. Aktualizuję lub wstawiam do tabeli zdarzeń, a także dodaję nowy rekord do tabeli tmp_event, a następnie odwiedzam zawartość w tmp_table, czy to zadziała? – Frank

+0

Tak, będzie. Dopóki nie wybierzesz opcji 'select' z tabeli, w której znajduje się wyzwalacz, nie spowoduje to wyświetlenia błędu wyzwalacza mutingu. – Annjawn

+0

@LucM Jaka funkcja? 'Mutating Trigger' jest błędem, który dotyczy wszystkich wersji bazy danych Oracle. – Annjawn