如何在 SAP HANA 上的数据库触发器中使用列列表

How to use a column list in a database trigger on SAP HANA

我正在尝试设置一个数据库触发器来记录一些更改信息。我想要实现的是,每当我的 table 的值更新时,用户名和日期也会被保存。我想在触发器中捕获它。

到目前为止我得到的是:

CREATE TRIGGER "MySchema"."updateTrigger"
AFTER UPDATE EXCEPT OF "ChangedBy", "ValidForm" ON "MySchema"."MySchema.database::model.MyTable"
REFERENCING NEW ROW mynewrow, OLD ROW myoldrow
FOR EACH ROW

BEGIN
    /* UPDATE status values in Request Table */
    UPDATE "MySchema"."MySchema.database::model.MyTable" 
        SET "ChangedBy" = CURRENT_USER, "ValidFrom" = CURRENT_TIMESTAMP
        WHERE "TableId"=:myoldrow.TableId;

我在 CREATE TRIGGER 中使用了这个 SAP help 页面。但是上面发布的代码不起作用。它返回以下内容:

sql syntax error: incorrect syntax near "EXCEPT"

所以我使用的是 AFTER UPDATE 触发器,但我需要在触发器内更新的字段除外,以免陷入无限循环。感谢所有帮助。

语法错误很可能是因为 EXCEPT 子句只进入了 HANA SPS12 的命令。您是 运行ning SPS12 还是更新版本?

无论如何,您采用的方法在很多层面上都不是很好,而且旧的 ABAP 数据建模仍然存在这一事实并没有真正使它变得更好。

  1. "LAST_CHANGER" 和 "LAST_CHANGED_DATE" 实际上不是用 table 建模的特定实体的一部分。它是应该保存在别处的元信息。

  2. 触发器是非常特定于平台的,因此您将 HANA 设置为此代码 运行 的唯一平台。但是,当您已经在一个平台上时,您不妨使用适当的平台服务来进行此类更改跟踪。在 HANA 中,它被称为 AUDIT,并为这种手工制作的触发器方法提供了一种更加灵活和安全的方法。

  3. 触发器过去、现在和将来都是管理和故障排除的噩梦。在不知道明确寻找它们的情况下,大多数时候它们都会在任何分析中被遗漏。由于他们在后台执行操作 'magically',因此出现副作用的可能性相当高。

  4. 触发器对 update/insert 性能也有相当大的影响,因为它们不会 运行 异步。

  5. 有了触发器,您就有了额外的代码来创建、维护和测试。知道怎么做吗?提到的 AUDIT 功能现在需要额外的编码,无需维护和测试。 此外,对 user_name 等 HANA 系统数据的依赖性会自动针对 AUDIT 功能进行管理。您的触发代码不会。考虑更改可能的用户名的长度(发生在早期的 HANA 版本中)。

知道所有这些论点都可能不会被注意,因为触发器对开发人员非常有吸引力,下面您将找到一个工作示例,说明如何完成这样的事情(在 SPS12 上 - 您可以省略除了早期版本的条款):

drop table mytab;
create column table mytab (id int, aaa nvarchar(20), bbb nvarchar(20), validfrom date, validto date,
                           last_changed timestamp, last_changer nvarchar(256));


create trigger update_trig 
before update except of validfrom, validto
on mytab
referencing new row newr 
for each row
begin
    newr.last_changed = current_utctimestamp;
    newr.last_changer = current_user;
end;

drop trigger insert_trig;
create trigger insert_trig 
before insert  
on mytab
referencing new row newr 
for each row
begin
    newr.last_changed = current_utctimestamp;
    newr.last_changer = current_user;
end;
truncate table mytab;

insert into mytab (id, aaa, bbb) values (1, 'bla', 'blupp');

select * from mytab;

/*
ID  AAA BBB     VALIDFROM   VALIDTO LAST_CHANGED            LAST_CHANGER
1   bla blupp   ?           ?       2016-12-19 23:10:46.866 DEVDUDE     
*/

update mytab set aaa='lala' where id = 1;

/*
ID  AAA     BBB     VALIDFROM   VALIDTO LAST_CHANGED            LAST_CHANGER
1   lala    blupp   ?           ?       2016-12-19 23:11:01.002 DEVDUDE     
*/

同样,仅仅因为它在 A 行用例中编译和工作,并不意味着它是个好主意。不是。