在另一個question我試圖創建一個hist表,它保留給定表的日誌。隨着這個問題的答案,我試圖創造新的東西。user_tab_columns何時更新?
因爲它是不可能創建表或視圖系統觸發,我創建了一個DDL觸發器是這樣的:
create or replace trigger ident_hist_trig after alter on schema
declare
v_table varchar2(30);
begin
select upper(ora_dict_obj_name) into v_table from dual;
if (v_table = 'Z_IDENT') then
prc_create_hist_tabel('z_ident_hist', 'z_ident');
elsif (v_table = 'D_IDENT') then
prc_create_hist_tabel('d_ident_hist', 'd_ident');
elsif (v_table = 'X_IDENT') then
prc_create_hist_tabel('x_ident_hist', 'x_ident');
else
null;
end if;
end;
/
過程prc_create_hist_tabel看起來是這樣的:
create or replace procedure prc_create_hist_tabel(p_naam_hist_tabel in varchar2, p_naam_tabel in varchar2) is
cursor c is
select 'alter table ' || p_naam_hist_tabel || ' add ' || column_name || ' ' || data_type || case when data_type = 'DATE' then null else '(' || data_length || ')' end lijn
from user_tab_columns
where TABLE_NAME = upper(p_naam_tabel)
and column_name not in (select column_name from user_tab_columns where table_name = upper(p_naam_hist_tabel));
v_dummy number(1);
cursor trig is
select column_name || ',' kolom, ':old.' || column_name || ',' old
from user_tab_columns
where table_name = upper(p_naam_tabel);
v_trigger_sql varchar2(32767);
begin
begin
select 1 into v_dummy
from user_tab_columns
where TABLE_NAME = upper(p_naam_hist_tabel)
group by 1;
exception when no_data_found then
execute immediate 'create table ' || p_naam_hist_tabel || ' (wijziger varchar2(60) default user, wijzigdatum date default sysdate, constraint pk_' || p_naam_hist_tabel || ' primary key (wijziger, wijzigdatum))';
end;
dbms_output.put_line('BBB');
for i in c
loop
begin
dbms_output.put_line(i.lijn);
execute immediate i.lijn;
exception when others then
dbms_output.put_line(i.lijn);
end;
end loop;
v_trigger_sql := 'create or replace trigger ' || p_naam_tabel || '_hist_trig after update on ' || p_naam_tabel || ' for each row begin insert into ' || p_naam_hist_tabel || ' (';
for v_lijn in trig
loop
v_trigger_sql := v_trigger_sql || v_lijn.kolom;
end loop;
v_trigger_sql := substr(v_trigger_sql, 1, length(v_trigger_sql) - 1);
v_trigger_sql := v_trigger_sql || ') values (';
for v_lijn in trig
loop
v_trigger_sql := v_trigger_sql || v_lijn.old;
end loop;
v_trigger_sql := substr(v_trigger_sql, 1, length(v_trigger_sql) - 1);
v_trigger_sql := v_trigger_sql || '); end;';
execute immediate v_trigger_sql;
end;
/
總之該功能所做的是維護歷史表。如果它不存在,它將創建一個,如果它存在,它會將新列添加到它。該過程還會創建一個新的觸發器,它將在更新後將舊值寫入歷史記錄表中。
但是,當我改變表x_ident,z_ident或d_ident之一,光標C將返回什麼(我可以檢查與打印時,我環路通過它)。雖然在之後執行選擇我改變了我的表格,但我確實得到了結果。
我從改變表d_ident得到的結果是這些:
BBB
d_ident: Table altered.
但我想它應該是周圍的其他方式,我認爲ALTER TABLE居然熄滅之前執行的程序prc_create_hist_tabel,我想我應該得到這樣的東西:
d_ident: Table altered.
BBB
任何幫助將被apreciated。我試圖在user_tab_columns上插入時創建一個觸發器,但是這給了我ORA-25001:無法在視圖上創建此觸發器類型。
我有休眠命令嘗試爲好,但也不能工作。