문제

트리거 내부에는 테이블의 모든 열을 루프하고 새 값을 이전 값과 비교하려고합니다. 지금까지 내가 가지고있는 것은 다음과 같습니다.

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 이미 트리거의 일부로 정의되어 있지만 즉시 실행하면 해당 변수를 볼 수 없습니다.

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

도움이 되었습니까?

해결책

아니요, 당신은 참조 할 수 없습니다 : 오래된 것과 : 새로운 값은 동적으로. 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;

(그건 그렇고 무의미한 참조 절을 버릴 수 있습니다).

다른 팁

당신이하려는 일을 할 수 있는지 확실하지 않습니다. PL/SQL 코드 내부의 테이블 열을 명시 적으로 이름을 지정하고 싶지 않은 이유는 무엇입니까? 테이블 필드가 자주 바뀌는 경우 각 테이블의 PL/SQL 트리거를 동적으로 빌드하는 PL/SQL을 빌드 할 수 있습니다 (각각의 명시 적 필드 이름이 있음). 테이블이 변경 될 때마다 PL/SQL을 실행하여 새 트리거를 생성 할 수 있습니다.

본질적으로 테이블의 모든 변경 사항을 감사하기 위해 자신의 시스템을 구축하려고합니까? (예전의 기존 및 새로운 값으로 무엇을 할 수 있는지에 대한 내 가장 좋은 추측.) 그렇다면 Oracle의 자체 감사 기능을 살펴볼 수 있습니다.

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

내 해결책은 테이블 및 열 정보 (사전보기 또는 사용자 정의 저장소를 통해)를 통해 반복하는 저장된 절차를 작성하고 필요한 트리거를 생성하는 것이 었습니다. 데이터 모델이 변경된 경우에만 절차를 실행해야합니다.

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

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top