如何在 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 数据建模仍然存在这一事实并没有真正使它变得更好。
"LAST_CHANGER" 和 "LAST_CHANGED_DATE" 实际上不是用 table 建模的特定实体的一部分。它是应该保存在别处的元信息。
触发器是非常特定于平台的,因此您将 HANA 设置为此代码 运行 的唯一平台。但是,当您已经在一个平台上时,您不妨使用适当的平台服务来进行此类更改跟踪。在 HANA 中,它被称为 AUDIT,并为这种手工制作的触发器方法提供了一种更加灵活和安全的方法。
触发器过去、现在和将来都是管理和故障排除的噩梦。在不知道明确寻找它们的情况下,大多数时候它们都会在任何分析中被遗漏。由于他们在后台执行操作 'magically',因此出现副作用的可能性相当高。
触发器对 update/insert 性能也有相当大的影响,因为它们不会 运行 异步。
有了触发器,您就有了额外的代码来创建、维护和测试。知道怎么做吗?提到的 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 行用例中编译和工作,并不意味着它是个好主意。不是。
我正在尝试设置一个数据库触发器来记录一些更改信息。我想要实现的是,每当我的 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 数据建模仍然存在这一事实并没有真正使它变得更好。
"LAST_CHANGER" 和 "LAST_CHANGED_DATE" 实际上不是用 table 建模的特定实体的一部分。它是应该保存在别处的元信息。
触发器是非常特定于平台的,因此您将 HANA 设置为此代码 运行 的唯一平台。但是,当您已经在一个平台上时,您不妨使用适当的平台服务来进行此类更改跟踪。在 HANA 中,它被称为 AUDIT,并为这种手工制作的触发器方法提供了一种更加灵活和安全的方法。
触发器过去、现在和将来都是管理和故障排除的噩梦。在不知道明确寻找它们的情况下,大多数时候它们都会在任何分析中被遗漏。由于他们在后台执行操作 'magically',因此出现副作用的可能性相当高。
触发器对 update/insert 性能也有相当大的影响,因为它们不会 运行 异步。
有了触发器,您就有了额外的代码来创建、维护和测试。知道怎么做吗?提到的 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 行用例中编译和工作,并不意味着它是个好主意。不是。