我正在尝试在PostgreSQL中创建一个update-audit触发器原型。
我正在将t_test的所有修改旧值记录到t_test_history以及新的值中。到目前为止,完美的工作。
但是现在我想在语句中记录所有更新行的更新语句的批处理ID。
说,我想在t_test上运行UPDATE t_test set b = 5 ;
,包含10个条目
我想要的是为这个“交易”分配一个id。
比方说,一个名为__batch_id的随机整数。
但是,如果我指定1到10之间的随机数
__batch_id := floor(random() * (10 + 1));
我(不出所料)看到每行的随机数不同。
当我想传递一个随机数来执行程序时,我得到了
“语法错误在或附近”(“”
EXECUTE PROCEDURE audit.log_test(now, random());
如何在不必将程序代码传递给update-statement的情况下获得这样的识别值,而无需将其写入临时表?
有可能吗?
如果它是自动增量而不是随机数,则奖励积分。
此外,我更喜欢在一个集合上执行此操作,而不是按行执行此操作。
这就是我所拥有的:
CREATE OR REPLACE FUNCTION audit.log_test()
RETURNS trigger AS
$BODY$
DECLARE
__operation_time timestamp without time zone;
__batch_id int;
BEGIN
__operation_time := TG_ARGV[0];
__batch_id := floor(random() * (10 + 1));
INSERT INTO t_test_history VALUES( __operation_time, user, __batch_id, OLD.*);
INSERT INTO t_test_history VALUES( __operation_time, user, __batch_id, NEW.*);
RETURN NEW;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
DROP TRIGGER IF EXISTS log_update on "public"."t_test";
CREATE TRIGGER log_update
AFTER UPDATE ON t_test
FOR EACH ROW
WHEN (OLD.* IS DISTINCT FROM NEW.*)
EXECUTE PROCEDURE audit.log_test(now, random()
);
这个(T-SQL示例)是我更喜欢的:
CREATE TRIGGER [dbo].[issues_trg_update_history] ON [dbo].[TestTable]
FOR UPDATE
AS
BEGIN
DECLARE @operation_time AS datetime = CURRENT_TIMESTAMP
DECLARE @operation_uid AS uniqueidentifier = NEWID()
SET NOCOUNT ON;
INSERT INTO dbo.TestTable_History
SELECT SUSER_SNAME(), 'update-deleted', @operation_time, @operation_uid, *
FROM deleted
;
INSERT INTO dbo.TestTable_History
SELECT SUSER_SNAME(), 'update-inserted', @operation_time, @operation_uid, *
FROM inserted
;
END
GO
EXEC sp_settriggerorder @triggername=N'[dbo].[issues_trg_update_history]', @order=N'Last', @stmttype=N'UPDATE'
GO
此外,关键字now
是否有效,但CURRENT_TIMESTAMP
会导致错误?