更新语句中所有PostgreSQL触发器行的值?

时间:2017-03-24 09:04:43

标签: postgresql triggers audit audit-trail

我正在尝试在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会导致错误?

0 个答案:

没有答案