INSERT ... RETURNING和pl / pgsql RETURN有什么区别?

时间:2014-03-12 16:39:44

标签: sql postgresql sql-insert

(交叉发布到pgsql-novice mailing list

假设如下:

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                                               

文档

Docs say of RETURN

  

使用表达式RETURN终止函数并返回   表达式的值给调用者。

Docs say of RETURNING

  

可选的RETURNING子句导致INSERT计算并返回   值(s)基于实际插入的每一行。

(强调我的)

我的问题是两个:

  1. 意义上的实际差异是什么 在这种情况下,这两个关键字之间的解释,以一种方式解释 允许我预测错误吗?

  2. 自触发器以来,错误的含义是什么? 函数需要返回一个值,因为INSERT是 触发函数的最终语句,为什么查询没有 结果数据的目的地?

1 个答案:

答案 0 :(得分:2)

请阅读此摘录(来自同一链接:http://www.postgresql.org/docs/9.3/static/sql-insert.html

  

如果INSERT命令包含RETURNING子句,则结果为   类似于包含列和的SELECT语句   在RETURNING列表中定义的值,通过行计算   由命令插入。

是的,我知道这个描述可能会令人困惑:)
简单来说:returns子句类似于SELECT,它从表中检索行,将它们组合成结果集,并将此结果集直接发送到客户端(客户端= gui工具,java / c ++程序等)。客户端必须知道如何使用某些API读取此结果集(打开它,从中检索行,值等) - 例如在java中有JDBC api用于处理结果集 - >寻找ResultSet类。

因此,returns子句创建一个结果集并将其发送到客户端 - 与普通SELECT一样。

函数中的return语句终止该函数,并将表达式的值返回给调用者。
不是直接对客户端,而是对调用者 - 调用此函数的其他函数/过程或SELECT语句。并且不会返回结果集(一组行),而是返回值。