다른 question 나는 주어진 테이블에서 로그를 유지하는 hist 테이블을 만들려고했습니다. 그 질문에 대한 답변으로 새로운 것을 만들려고 노력했습니다.언제 user_tab_columns가 업데이트 되나요?
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;
/
가 테이블 또는 뷰의 시스템 트리거를 생성 할 수 없으므로
는 I 이런 DDL 트리거를 생성 그 기능이하는 일은 역사표를 유지하는 것입니다. 존재하지 않으면 생성 된 것이고, 존재한다면 새로운 열을 추가합니다. 또한 프로 시저는 갱신 후 히스토리 테이블에 이전 값을 기록하는 새 트리거를 작성합니다.
그러나 x_ident, z_ident 또는 d_ident 테이블 중 하나를 변경하면 커서 c는 아무 것도 반환하지 않습니다.이 커서를 통해 루프 할 때 인쇄물을 확인할 수 있습니다. 테이블을 변경 한 후에 을 선택하면 결과가 나타납니다. 나는 테이블 변경이 실제로 해제되기 전에 프로 시저 prc_create_hist_tabel 실행하고 있다고 생각,
BBB
d_ident: Table altered.
그러나 나는 다른 방법으로 주위해야한다 생각 : 나는 테이블 d_ident을 변경에서 얻을
결과이 있습니다 그리고 나는 다음과 같은 것을 얻어야한다고 생각합니다 :
d_ident: Table altered.
BBB
도움이 될 것입니다. user_tab_columns에 삽입 할 때 트리거를 만들려고했으나 ORA-25001 : 뷰에서이 트리거 유형을 만들 수 없습니다.
나는 sleep 명령을 시도했지만 그 중 하나도 작동하지 않았습니다.