postgresql – 在触发器函数中,如何获取更新哪些字段

前端之家收集整理的这篇文章主要介绍了postgresql – 在触发器函数中,如何获取更新哪些字段前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
这可能吗?我有兴趣了解在UPDATE请求中指定了哪些列,而不管事实上,正在发送的新值可能是也可能不是存储在数据库中的。

我想这样做的原因是因为我们有一个表可以从多个来源接收更新。以前,我们没有记录更新来源的来源。现在,该表存储哪些来源已经执行了最新的更新。我们可以更改一些来源来发送标识符,但这不是一切的选择。所以我想能够识别UPDATE请求何时没有标识符,因此我可以用默认值替换。

像@ A.H。在他的评论中写道,如果“源”没有“发送标识符”,列将不会更改。那么你不能检测当前的UPDATE是由与最后一个相同的源完成的,还是根本没有更改列的源。换句话说:这不能正常工作。

如果“源”可以通过these session information functions中的任何一个来识别,你可以使用它。喜欢:

NEW.column = session_user;

无条件地为每一次更新。

一般解决方

我找到了一个如何解决原来的问题。在列不更新的任何更新(不在UPDATE的SET列表中),该列将被设置为默认值。

关键要素是Postgresql 9.0中引入的per-column triggers

The trigger will only fire if at least one of the listed columns is
mentioned as a target of the UPDATE command.

这是我找到的唯一简单的方法来区分列是否更新与旧值相同的新值,而不是更新。
可以解析current_query()返回的文本。

我假设列coligned NOT NULL。

>步骤1:如果不变,将col设置为NULL:

CREATE OR REPLACE FUNCTION trg_tbl_upbef_step1()
  RETURNS trigger AS
$BODY$
BEGIN

IF OLD.col = NEW.col THEN
    NEW.col := NULL;        -- "impossible" value
END IF;

RETURN NEW;

END;
$BODY$  LANGUAGE plpgsql;

> Step2:恢复旧值触发器将仅被触发,如果该值实际更新:

CREATE OR REPLACE FUNCTION trg_tbl_upbef_step2()
  RETURNS trigger AS
$BODY$
BEGIN

IF NEW.col IS NULL THEN
    NEW.col := OLD.col;
END IF;

RETURN NEW;

END;
$BODY$  LANGUAGE plpgsql;

>步骤3:现在我们可以识别缺少的更新,并设置一个默认值:

CREATE OR REPLACE FUNCTION trg_tbl_upbef_step3()
  RETURNS trigger AS
$BODY$
BEGIN

IF NEW.col IS NULL THEN
    NEW.col := 'default value';
END IF;

RETURN NEW;

END;
$BODY$  LANGUAGE plpgsql;

实现触发器,step2是每列触发器:

CREATE TRIGGER upbef_step1
  BEFORE UPDATE ON tbl
  FOR EACH ROW
  EXECUTE PROCEDURE trg_tbl_upbef_step1();

CREATE TRIGGER upbef_step2
  BEFORE UPDATE OF col ON tbl               -- key element
  FOR EACH ROW
  EXECUTE PROCEDURE trg_tbl_upbef_step2();

CREATE TRIGGER upbef_step3
  BEFORE UPDATE ON tbl
  FOR EACH ROW
  EXECUTE PROCEDURE trg_tbl_upbef_step3();

触发器的名称是相关的,因为它们将按字母顺序被触发!

如果我们有一些类似“per-not-column”的触发器,或任何其他方式可以轻松地检查触发器中UPDATE的目标列表,那么可以简化这个过程。

如果您的列可以为NULL,请使用任何其他“不可能”的温度。值并检查NULL另外:

IF OLD.col IS NOT DISTINCT FROM NEW.col THEN
    NEW.col := '#impossible_value#';
END IF;

猜你在找的Postgre SQL相关文章