2016-09-19 70 views
-2

我想記錄一個名爲Tables_History的表中的所有表更改,每個表具有一個觸發器,並且沒有尋址列名稱的明確性,並且根據列的類型。因爲我有50張桌子,因爲有不同的項目。許多開發人員可能會更改表格的結構。所以我不能列出明確的列名。這是Tables_History的defenition:在Oracle中審計DML更改

create table Tables_History 
(
    user_id  VARCHAR2(10) not null, 
    change_date DATE not null, 
    table_name  VARCHAR2(100) not null, 
    column_name VARCHAR2(100) not null, 
    primary_key_id INTEGER not null, 
    old_number  NUMBER, 
    new_number  NUMBER, 
    old_string  VARCHAR2(900), 
    new_string  VARCHAR2(900), 
    old_date  DATE, 
    new_date  DATE, 
    ... 
    . 
); 

如果有任何的方式來訪問:在觸發新的列值,通過將列名作爲參數,而不是標準的方式(:new.column_name)。像這樣(:new ['column_name'])。
這是我爲一個表(然後我可以複製粘貼+這觸發其他表,改變只有幾參數:-D)理想觸發:

create or replace trigger Audit_TableName 
    before update on TableName 
    for each row 
declare 
    v_query varchar(32767); 
    UserCode varchar(10); 
begin 

    SELECT sys_context('USERENV', 'CLIENT_IDENTIFIER') 
    INTO UserCode 
    FROM DUAL;    

    FOR getrec IN (SELECT column_name, data_type 
        FROM all_tab_columns 
        WHERE table_name = 'TableName' 
        AND owner = 'MEHRAN' 
        AND data_type <> 'BLOB') LOOP 
    if Updating(getrec.column_name) then 
     if getrec.data_type = 'NUMBER' then 
     v_query := 'insert into Tables_History(user_id,change_date,table_name,column_name,primary_key_id,,,OLD_NUMBER, NEW_NUMBER)' 
      ||'values('..,..,..,..||:old[getrec.column_name]||','||:new[getrec.column_name]||')'; 
     else if getrec.data_type = 'VARCHAR2' then 
     v_query := 'insert into Tables_History(...,...,... OLD_VARCHAR, NEW_VARCHAR)' 
      ||'values(...,...,..'||:old[getrec.column_name]||','||:new[getrec.column_name]||')'; 
     ... 
     . 
     . 
     end if; 
     EXECUTE IMMEDIATE v_query; 
    end if; 
    END LOOP; 

end Audit_TableName; 
+0

嘗試打印您構建的動態查詢;這會給你一些提示來編輯你的代碼 – Aleksej

+0

我不認爲這是可能的使用觸發器。即使你把它變成動態的,我懷疑它會起作用。順便說一句,你爲什麼要這樣做。 – XING

+0

在這方面提供一些更多的細節。告訴我們你希望你的觸發器看起來一樣嗎?共享您需要的示例代碼或輸出。 –

回答