我想将我的working表的更改记录到我的history表中,但仅当值在 UPDATE 期间发生更改时,我尝试创建一个 update_history 触发器,但无论值是否已更改,它都会添加一行,例如说我有这在我的工作表中:
shift_id|site |organisational_unit
--------|---------|-------------------
123475|site01 |my org
Run Code Online (Sandbox Code Playgroud)
如果我执行更新查询
UPDATE working SET site = $1, organisational_unit = $2 WHERE shift_id=$3', ['site01', 'my new org', '123475']
Run Code Online (Sandbox Code Playgroud)
这会在历史记录表中创建一行,因为site 它甚至认为它没有更改值我只想要一个新行用于组织单元更改
historyid|shiftid|fieldname |oldvalue |newvalue |updatedat |
---------|-------|-------------------|---------|-----------|-------------------|
7| 123475|organisational_unit|my org |my new org |2019-07-01 10:21:19|
8| 123475|site |site01 |site01 |2019-07-01 10:21:19|
Run Code Online (Sandbox Code Playgroud)
我的触发器看起来像这样
-- create function for updates to track history
CREATE function update_history ()
RETURNS TRIGGER
as $$
BEGIN
-- check if data in column has changed between the update
IF NEW.client_id <> OLD.client_id THEN
-- if it has insert a row to the history table detailing the changes
INSERT INTO history (ShiftId, fieldName, OldValue, NewValue)
VALUES(New.shift_id, 'client id ', OLD.client_id, NEW.client_id);
-- if nothing has changed don't do anything
END IF;
IF NEW.organisational_unit <> OLD.organisational_unit THEN
INSERT INTO history (ShiftId, fieldName, OldValue, NewValue)
VALUES(New.shift_id, 'organisational_unit', OLD.organisational_unit, NEW.organisational_unit);
END IF;
IF NEW.site <> OLD.site THEN
INSERT INTO history
(ShiftId, fieldName, OldValue, NewValue)
VALUES(New.shift_id, 'site', OLD.site, NEW.site);
END IF;
return null;
END;
$$
language plpgsql;
Run Code Online (Sandbox Code Playgroud)
要检查列是否已更改,请勿使用<>。它不考虑空值。使用IS DISTINCT FROM
IF NEW.client_id IS DISTINCT FROM OLD.client_id
...
Run Code Online (Sandbox Code Playgroud)
或者使用检查整行IF NEW IS DISTINCT FROM OLD
如果你想阻止插入主表的发生,它应该是一个BEFORE UPDATE触发器,你应该做一个
return null;
仅在您不想要的地方INSERT
最有效的方法是定义一个仅在某些列更改时触发的触发器:
CREATE TRIGGER ... BEFORE UPDATE ON ... FOR EACH ROW
WHEN (NEW IS DISTINCT FROM OLD)
EXECUTE FUNCTION update_history();
Run Code Online (Sandbox Code Playgroud)
这避免了在不必要的情况下执行函数。
| 归档时间: |
|
| 查看次数: |
286 次 |
| 最近记录: |