2009-04-24 4 views
3

트리거 내에서 테이블의 모든 열을 반복하고 새로운 값을 이전 값과 비교하려고합니다.오라클 PL/SQL : 루프 트리거 트리를 동적으로

CREATE OR REPLACE TRIGGER "JOSH".TEST#UPD BEFORE 
UPDATE ON "JOSH"."TEST_TRIGGER_TABLE" REFERENCING OLD AS OLD NEW AS NEW FOR EACH ROW 
declare  
    oldval varchar(2000); 
    newval varchar(2000); 
begin  
    for row in (SELECT column_name from user_tab_columns where table_name='TEST_TRIGGER_TABLE') loop 
    execute immediate 'select :old.'||row.column_name||' from dual' into oldval; 
    execute immediate 'select :new.'||row.column_name||' from dual' into newval; 
    --Do something here with the old and new values 
    end loop; 
end; 

트리거가 컴파일하지만 트리거 화재, 내가 받고있을 때 :

ORA-01008를 : 여기에 지금까지 무엇을 가지고 모든 변수

바인딩 처음에는 :old에 대한 값을 기대하기 때문에 즉시 실행됩니다. :old:new은 이미 트리거의 일부로 정의되어 있지만 즉시 실행은 해당 변수를 볼 수 없습니다.

트리거의 열 값을 동적으로 반복하는 방법이 있습니까?

+1

: 이전 및 : 새 키워드는 트리거가 각 행에 대해 지정하는 경우에만 사용할 수 있습니다. – Powerlord

+0

오른쪽 "FOR EACH ROW"가 지정됩니다. 문제는 동적 SQL 문에서 참조하려고한다는 것입니다. –

+0

혼란을 피하기 위해 트리거를 생성하는 데 사용하는 전체 DDL을 추가했습니다. –

답변

5

아니요, 이전 값과 새로운 값을 동적으로 참조 할 수 없습니다. 셰인 (Shane)이 말했듯이, 정적 트리거 코드를 생성하는 코드를 작성할 수 있습니다.

CREATE OR REPLACE TRIGGER JOSH.TEST#UPD BEFORE 
UPDATE ON JOSH.TEST_TRIGGER_TABLE 
begin  
    my_package.do_something_with (:old.col1, :new.col1); 
    my_package.do_something_with (:old.col2, :new.col2); 
    my_package.do_something_with (:old.col3, :new.col3); 
    -- etc. 
end; 

(당신은 방법에 의해 의미가 REFERENCING 절을 도랑 수) : 또한, 당신은 당신의 트리거가되도록 패키지 프로 시저에 "여기에 무언가를"할 수 있습니다.

4

당신이하려는 일을 할 수 있는지 확실하지 않습니다. PL/SQL 코드에서 명시 적으로 테이블 열 이름을 지정하지 않으려는 이유는 무엇입니까? 테이블 필드가 자주 변경되는 경우 각 테이블에 대해 명시 적 필드 이름을 사용하여 동적으로 PL/SQL 트리거를 작성하는 PL/SQL을 작성할 수 있습니다. 테이블이 변경 될 때마다 PL/SQL을 실행하여 새 트리거를 생성 할 수 있습니다.

+1

나는 이것이 사실일지도 모른다는 것에 대해 두려워했다. 나는 가능한 한 간단하게 코드를 유지하려고 노력하고 있었으며 반복적으로 같은 코드의 큰 혼란을 피했다. –

2

MSSQL에서도 비슷한 문제가있었습니다.

내 솔루션은 테이블 및 열 정보를 통해 사전 뷰 또는 사용자 지정 리포지토리를 통해 반복하고 필요한 트리거를 생성하는 저장 프로 시저를 작성하는 것이 었습니다. 데이터 모델이 변경된 경우에만 프로 시저를 실행해야합니다.

장점은 각 업데이트에서 메타 모델을 통해 커서를 이동할 필요가 없으며 미리 트리거를 생성해야한다는 것입니다.

4

기본적으로 테이블에 대한 모든 변경 사항을 감사하기 위해 자체 시스템을 구축하려고합니까? (필자가 임의의 열의 이전 값과 새로운 값으로 무엇을 수행하고 있는지 추측 할 수 있습니다.) 그렇다면 오라클 자체의 감사 기능을 살펴 보는 것이 좋습니다.