(交叉发布到pgsql-新手邮件列表)
假设如下:
CREATE TABLE base_foo (size int);
CREATE VIEW foo AS SELECT * FROM base_foo;
CREATE FUNCTION insert_foo() RETURNS TRIGGER AS
$$BEGIN
INSERT INTO base_foo VALUES (NEW.size);
RETURN NEW;
END$$ language plpgsql;
CREATE TRIGGER insert_foo INSTEAD OF INSERT ON foo
FOR EACH ROW execute PROCEDURE insert_foo();
观察此行为
我可以插入到我的视图中:
INSERT INTO foo VALUES (2);
工作;没有问题。现在,如果我把触发函数改成
而不是两个语句,第二个是RETURN
,它是一个INSERT
加RETURNING
子句,如下:
CREATE OR REPLACE FUNCTION insert_foo() RETURNS TRIGGER AS
$$BEGIN
INSERT INTO base_foo VALUES (NEW.size)
RETURNING NEW;
END$$ language plpgsql;
则插入导致错误:
INSERT INTO foo VALUES (3);
ERROR: query has no destination for result data
CONTEXT: PL/pgSQL function insert_foo() line 2 at SQL statement
医生说的返回:
带表达式的RETURN终止函数并返回值给调用者。
文档说明:
我可选的RETURNING子句导致INSERT计算并返回值基于实际插入的每一行。
(重点)
我的问题有两个:
实际意义上的区别是什么在这两个关键词之间的上下文中,用一种方式说明允许我预测误差吗?
错误的含义是什么,即。,自触发函数需要返回一个值,并且由于
INSERT
是最后语句的触发函数,为什么查询没有结果数据的目的地?
请阅读此节选(来自同一链接:http://www.postgresql.org/docs/9.3/static/sql-insert.html)
如果INSERT命令包含return子句,结果将是类似于包含和列的SELECT语句在RETURNING列表中定义的值,按行计算由命令插入。
是的,我知道这个描述可能会让人困惑:)
简单来说:return子句的工作原理类似于SELECT,它从表中检索行,将它们组合成一个结果集,并将这个结果集直接发送给客户端(客户端= gui工具,java/c++程序等)。客户端必须知道如何读取这个结果集(打开它,从中检索行,值等),使用一些API -例如在java中有用于处理结果集的JDBC API ->查找ResultSet
类。
因此,返回子句创建一个结果集并将其发送给客户端——与普通SELECT的方式相同。
函数中的Return语句终止该函数,并将表达式的值返回给调用者。
不是直接发送给客户端,而是发送给调用者——发送给调用该函数的其他函数/过程或SELECT语句。并且不返回结果集(一组行),而是返回值。