【问题标题】:PostgreSQL trigger not returning anythingPostgreSQL 触发器不返回任何内容
【发布时间】:2011-10-30 23:58:38
【问题描述】:

我在创建时有一个 PostgreSQL 触发器,它基本上将插入重定向到子表中。插入记录后,我想中止请求以避免重复数据。唯一的方法(据我所知)是在触发器中返回NULL。问题是我需要返回记录,以便获取 ID。如果我返回NULL,我会得到...NULL

知道如何让触发器中止操作,同时仍返回 NULL 以外的其他内容吗?

【问题讨论】:

  • 所以你试图在表 X 上构建一个触发器,将数据插入 Y 和 Z,防止任何东西插入 X,但返回一些 ID?
  • 是的,我将数据分区到继承的表中。所以我不希望父表中有重复的行。我基本上希望这个过程是完全透明的。你处理父表,触发器在幕后做所有事情。从外面看没有任何变化。

标签: postgresql triggers plpgsql


【解决方案1】:

您的问题留有解释的余地​​。按照我的理解,您希望INSERT 命令的RETURNING 子句返回由序列生成的主键的值。

还有其他方法可以实现这一点。就像使用nextval() 预先从序列中获取下一个id 并插入带有id 拼写出来的行。
currval() / lastval() 获取当前会话中序列/任何序列的最新获得值。更多相关答案:
PostgreSQL next value of the sequences?

您也可以为此使用RULE ... INSTEAD ..

但是,要回答您的问题 - 如果这实际上是您的问题:可以通过使用两个触发器来完成。一个BEFORE,一个AFTER INSERT。 两者都在每个定义的一个事务中触发,因此您的第一个表中的幻像行对任何人都不可见(触发器除外)。

演示:

CREATE TABLE x (
  id serial PRIMARY KEY  -- note the serial col.
 ,name text
);

CREATE TABLE y (
  id integer PRIMARY KEY
 ,name text
);


CREATE OR REPLACE FUNCTION trg_x_insbef()
  RETURNS trigger AS
$func$
BEGIN
  INSERT INTO y SELECT (NEW).*;  -- write to other table
  RETURN NEW;
END
$func$ LANGUAGE plpgsql;

CREATE TRIGGER insbef
  BEFORE INSERT ON x
  FOR EACH ROW EXECUTE PROCEDURE trg_x_insbef();


CREATE OR REPLACE FUNCTION trg_x_insaft()
  RETURNS trigger AS
$func$
BEGIN
  DELETE FROM x WHERE id = NEW.id; -- delete row again.
  RETURN NULL;
END
$func$ LANGUAGE plpgsql;

CREATE TRIGGER insaft
  AFTER INSERT ON x
  FOR EACH ROW EXECUTE PROCEDURE trg_x_insaft();

在 psql 中调用:

db=# INSERT INTO x (name) values('phantom') RETURNING id;
 id
----
  1
(1 row)

INSERT 0 1

db=# SELECT * FROM x;
 id | name
----+------
(0 rows)


db=# SELECT * FROM y;
 id |  name
----+---------
  1 | phantom
(1 row)

【讨论】:

  • 谢谢!这正是我想要的结果。我关心的是性能,添加一行然后删除它。我知道它不是一个大热门,只是看起来很乱。不能以其他方式做到这一点吗?感谢您的帮助。
  • 我确信还有其他方法,但这就是您所要求的。我暗示在我的回答中使用 nextval() 。你看见了吗? (加链接。)这就是我可以做到的。 nextval() 的缺点:再调用一次服务器。所以这取决于情况会更快。我的示例是一种解决方法,但使用起来应该非常安全。
猜你喜欢
  • 2016-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-20
  • 1970-01-01
  • 2020-04-27
  • 2019-04-06
  • 2012-02-15
相关资源
最近更新 更多