因此,此问题的评论提到,PostgreSQL中的“存储过程”和“存储功能”略有不同。

该评论链接到Wikipedia文章,但其中一些似乎没有可以应用(例如,它们可以在SELECT语句中使用)。

语法本身似乎有点令人困惑:

CREATE FUNCTION emp_stamp() RETURNS trigger AS $emp_stamp$
    BEGIN
       [...]
    END;
$emp_stamp$ LANGUAGE plpgsql;

CREATE TRIGGER emp_stamp BEFORE INSERT OR UPDATE ON emp
    FOR EACH ROW EXECUTE PROCEDURE emp_stamp();


您创建了一个FUNCTION,但将其称为PROCEDURE

那么两者之间有什么区别?

#1 楼

正式地,PostgreSQL仅具有“功能”。触发器功能有时被称为“触发过程”,但是用法没有明显的含义。在内部,有时将功能称为过程,例如在系统目录pg_proc中。这是PostQUEL的保留。某些人(可能具有不同数据库系统的经验)可能与过程相关联的任何功能,例如它们与防止SQL注入的相关性或使用输出参数的功能,也适用于PostgreSQL中存在的功能。

现在,当PostgreSQL社区中的人们谈论“存储过程”或“实际存储过程”时,它们通常意味着一个函数式对象的假设特征,该对象可以在其主体中启动和停止事务,这是当前的情况。功能不能做到。在这种情况下,术语“存储过程”的使用似乎类似于其他数据库产品。请参阅此邮件列表主题以了解模糊的想法。

但是,实际上,功能和过程在事务控制能力方面的这种区别并未得到普遍接受,并且当然,许多没有数据库偏见的程序员会对过程进行类似Pascal的解释,将其视为没有返回值的函数。 (SQL标准似乎具有中间立场,因为默认情况下过程与函数具有不同的事务行为,但是可以针对每个对象进行调整。)因此,在任何情况下,尤其是在使用Stack Exchange查看问题时,尤其如此。受众非常混杂的情况下,您应该避免假设太多,并使用更清晰的术语或定义期望的属性。

评论


值得一提的是,Postgres 11已添加了真正的过程。某个特定功能的主要作者是Peter Eisentraut。

–欧文·布兰德斯特(Erwin Brandstetter)
20年8月30日在22:25



#2 楼

就DDL而言,Postgres没有过程对象,只有函数。 Postgres函数可以返回值,也可以返回void,因此它们在其他RDBMS中担当了函数和过程的角色。 create trigger中的“过程”一词指的是函数。

就Postgres文档而言,“过程”也是数据库对象称为函数的同义词,例如:使用CREATE FUNCTION命令创建。”

触发器“过程”确实具有特定的规则:它们必须声明为不带参数且返回类型为触发器的函数。这里的例子。

#3 楼

术语“存储过程”和“存储函数”在PostgreSQL中可以互换使用,并且通常表示同一事物。其他数据库可能会区分过程和函数(类似于VB如何区分子例程和函数)。

只要PostgreSQL中的函数返回类似于表的内容,您就可以使用该输出功能就像是标准表一样。 CREATE TRIGGER语法有点混乱,但是我怀疑在ANSI标准最终定稿之前可能已经存在。我只有SQL:2003的副本,因此我只能做些什么,以推测为什么命名法很怪异。

TL; DR版本:使用PostgreSQL的“过程”等同于“函数” 。

#4 楼

简短的答案是一个函数返回一个值,但是一个过程却没有。

这种区别存在于针对SQL 1992的持久存储模块(SQL / PSM)中。我不知道SQL / PSM是否曾经成为标准。

评论


我相信到2003年

– xenoterracide
2011-4-25 11:50

这听起来很像VB的语法。一个函数返回一个值,而一个过程则不返回(因此,如果函数中有一个返回值,它将在编译器中崩溃)

– jcolebrand♦
2011年4月25日在21:28

@jcolebrand实际上,这些名字在Pascal中更为明显。过程不返回结果,而函数则返回结果。由于历史原因,VBA使用FORTRAN语言,将其称为(称为?)SUBROUTINE&FUNCTION。现代C类型语言仅具有函数,但是类型化语言可以选择void函数,后者是另一个过程。一种流行的趋势是仅对所有内容使用常规函数,并返回一些您可以忽略的东西。

– Manngo
17年2月17日在23:38

#5 楼

在MSSQL中,存储过程是一组预编译的sql命令。
存储过程:
 - can have many input and output paramters
 - can be used to modify database tables/structures/data
 - are not normally used inside insert/update/delete/select statements

用户定义的函数有几种形式。根据所编写函数的类型,函数:
  - can have multiple input parameters, but only return a single value (i.e. string concatenation)
  - can accept a set as an input, return a single value (i.e. dbo.FindLargestPig(ListOfPigs)  )
  - return a table (i.e. select * from dbo.ExplodeString("this is a list of words")  )
  - can be used in select/insert/update/delete statements
  - CANNOT be used to modify database tables/structures/data


#6 楼

PostgreSQL 11将存储过程添加为新的模式对象。您可以使用CREATE PROCEDURE语句创建一个新过程。
存储过程在以下方面不同于函数:


存储过程不必返回任何内容,而仅返回使用INOUT参数时仅一行。


您可以在存储过程中提交和回滚事务,但不能在函数中进行。


执行使用CALL语句而不是SELECT语句存储过程。


与函数不同,过程不能嵌套在其他DDL命令(SELECTINSERTUPDATEDELETE)中。



#7 楼

从抽象的概念层次比较接受的答案,我从功能和输入/输出角度理解了差异。下面我用sp和f分别表示存储过程和函数。



在表达式中使用:sp不能在表达式中使用,而function可以,这意味着可以在其他语句中使用从af返回的值,例如

select * 
from table 
where col_a < (select col_A from f())


返回值:除非您指定refcursor返回类型,打开并返回,否则sp不会自动返回值光标f在最后一个语句中返回结果,该语句中嵌入了“ return”子句,如select子句。
返回单个/多个结果集:这里的结果集指的是格式可能不同的结果列表,例如单个整数,文本数组和两个表的集合。只要您指定refcursor返回类型,sp即可返回多个集合,打开并返回一个游标。但是,f只能返回一种类型的集合。通常,存储过程用于修改不需要返回值的数据库数据或结构,例如删除,更新,删除等。或需要多个结果集的情况。另一方面,函数通常是为简单查询选择的。

有关我的解释的更多详细信息,请参考以下链接:PostgreSQL中的存储过程和函数