加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-13 16:37:29 所属栏目:百科 来源:网络整理
导读:这可能吗?我有兴趣了解在UPDATE请求中指定了哪些列,而不管事实上,正在发送的新值可能是也可能不是存储在数据库中的。 我想这样做的原因是因为我们有一个表可以从多个来源接收更新。以前,我们没有记录更新来源的来源。现在,该表存储哪些来源已经执行了最
这可能吗?我有兴趣了解在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;

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读