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

update语句中所有PostgreSQL触发器行的值?,postgresql,triggers,audit,audit-trail,Postgresql,Triggers,Audit,Audit Trail,我试图在PostgreSQL中创建一个更新审计触发器原型 我将所有修改过的t_test旧值记录到t_test_历史记录中,以及新值。到目前为止,它工作得很好 但是现在我想为语句中所有更新的行记录update语句的批处理id 比如说,我想运行updatet_测试集b=5在t_测试中有10个条目 我想要的是为这个“事务”分配一个id 比如说,一个名为uu batch_id的随机整数。 但是如果我分配一个介于1和10之间的随机数 __batch_id := floor(random() * (10

我试图在PostgreSQL中创建一个更新审计触发器原型
我将所有修改过的t_test旧值记录到t_test_历史记录中,以及新值。到目前为止,它工作得很好

但是现在我想为语句中所有更新的行记录update语句的批处理id

比如说,我想运行
updatet_测试集b=5在t_测试中有10个条目

我想要的是为这个“事务”分配一个id
比如说,一个名为uu batch_id的随机整数。
但是如果我分配一个介于1和10之间的随机数

 __batch_id := floor(random() * (10 + 1));
我(毫不奇怪)发现每一行都是不同的随机数
当我想传递一个随机数来执行这个过程时,我得到

“处或附近出现语法错误”(“”

我怎样才能拥有这样一个标识值,而不必将其从程序代码传递到update语句,也不必将其写入临时表?
有可能吗?
如果是自动递增而不是随机数,则可获得额外积分。
此外,我更喜欢在一组中进行,而不是在每行的基础上进行

这就是我所拥有的:

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\u TIMESTAMP
导致错误的具体原因是什么?

问题是对update语句中所有受影响的行获取相同的值,而不是插入该值。不,不能从旧表中选择。*,它不是表。顺便说一句,这也是我的第一个错误()您需要一个语句级触发器+加上一个行级触发器,将受影响的行存储在一个中间临时表中(目前在Postgres中没有与SQL Server的
deleted
“table”等效的触发器,但可能会随10.0而改变),您可以使用Postgres的内部事务id:
txid\u current()
:@a_horse_with_no_name:非常感谢,这似乎很有效。date+txid的组合应该是唯一的。顺便问一下:您是否注意到:或者:这些是审计触发器,用于在hstore或json列中存储新旧值之间的差异(而不必为每次修改创建两行)问题是为update语句的所有受影响行获取相同的值,而不是插入该值。不,您不能从old.*中选择,它不是表。这也是我的第一个错误,顺便说一下。()您需要一个语句级触发器+加一个行级触发器,将受影响行存储在中间临时表中(目前,在Postgres中,SQL Server的
已删除的
“表”没有等价物,但这可能会随着10.0而改变)您可以使用Postgres的内部事务id:
txid_current()
:@a_horse_with_no_name:非常感谢,这似乎很有效。date+txid的组合应该是唯一的。顺便问一下:您是否注意到:或者:这些是审计触发器,用于在hstore或json列中存储新旧值之间的差异(而不必为每次修改创建两行)
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