我如何连接 :NEW 或 :OLD 与变量?

HOW CAN I CONCATENATE :NEW OR :OLD WITH A VARIABLE?

create or replace TRIGGER TEST_TRIGG
BEFORE UPDATE ON ALUMNES
FOR EACH ROW
DECLARE
updatedcols varchar2(3000);
begin
for r in (select column_name from user_tab_columns where table_name ='ALUMNES')
    loop
       IF UPDATING(r.column_name) THEN
       updatedcols := updatedcols || ',' || r.column_name;
        INSERT INTO control_de_dades_alumnes (TIPUS_OPERACIO, USUARI, DIA, COLUMNA, DADA_ANTIGA) VALUES ('UPDATE', USER, SYSDATE, updatedcols, :OLD.updatedcols);
       END IF;
    end loop;
end;

enter image description here

如何将 :NEW 或 :OLD 与变量连接起来 # Oracle #Script #Concatenate。

使用 Select 我收集了我正在更新的列的名称,并将其存储在一个名为 updatedcols 的变量中,以便我想将变量与 :OLD 连接起来以收集该列的旧数据领域,但它不允许我。

非常感谢

您无法动态访问 :new:old pseudo-records 的属性。您需要有一系列静态 if 语句

IF updating( 'COLUMN1' )
THEN
  updatedCols := updatedCols || ', ' || :new.column1;
END IF; 
IF updating( 'COLUMN2' )
THEN
  updatedCols := updatedCols || ', ' || :new.column2;
END IF;

当然,您可以编写一些代码来使用数据字典 table,例如 user_tab_columns,以生成包含所有静态列引用的触发器代码。这通常比仅静态编写触发器要付出更多的努力,但如果您尝试在大量 table 上创建类似的触发器,这可能是值得的。您还需要确保您的开发过程包括每次有人从 table.

添加或删除列时重新生成触发器

顺便说一句,如果触发 update 语句包含 column1,请注意 updating( 'COLUMN1' ) returns 为真,无论 column1 中的值是否实际更改.如果您试图捕捉变化,那很少是您真正想要的。您通常希望将 :new.column1:old.column1 进行比较,以查看值是否确实发生了变化。

作为一种通用的架构方法,根据我的经验,使用单个日志 table 来存储来自一堆不同 table 的更改很少能奏效。如果系统变得流行,日志 table 会变得如此之大以至于几乎无法有效查询。很难回答诸如“2022 年 1 月 15 日 4:15 下午 id = 12345 的行中 column1 的值是多少”这样的问题,在您的情况下,这实际上是不可能,因为你的日志 table 中没有任何内容告诉你哪一行的数据发生了变化。