“存储过程”和“存储函数”之间有什么区别?


36

因此,该问题的评论提到,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

那么这两者有什么区别?

Answers:


43

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

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

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


14

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

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

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


8

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

只要PostgreSQL中的函数返回类似于表的内容,就可以使用该函数的输出,就好像它是标准表一样。的CREATE TRIGGER语法是有点混乱,但我怀疑它可能已经到位的ANSI标准定稿之前。我只有SQL:2003的一个副本,所以我只能推测为什么命名法很奇怪。

TL; DR版本:在PostgreSQL中,“过程”等效于“功能”。


6

在MSSQL中,存储过程是一组预编译的sql命令。
存储过程:

 -可以有很多输入和输出参数
 -可用于修改数据库表/结构/数据
 -通常不在插入/更新/删除/选择语句中使用
用户定义的函数有几种形式。根据编写的函数类型,函数:
  -可以有多个输入参数,但只能返回一个值(即字符串连接)
  -可以接受集合作为输入,返回单个值(即dbo.FindLargestPig(ListOfPigs))
  -返回表(即从dbo.ExplodeString(“这是单词列表”)中选择*))
  -可用于选择/插入/更新/删除语句
  -不能用于修改数据库表/结构/数据


5

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

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


我相信到2003年
xenoterracide

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

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

2

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

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

    select * 
    from table 
    where col_a < (select col_A from f())
  2. 返回值:sp不会自动返回值,除非您指定refcursor返回类型,打开并返回游标;f在最后一个语句中返回结果,该语句中嵌入了“ return”子句,如select子句。

  3. 返回单个/多个结果集:此处的结果集是指格式可能不同的结果列表,例如单个整数,文本数组和两个表的集合。只要您指定refcursor返回类型,sp即可返回多个集合,打开并返回一个游标。但是,f只能返回一种类型的集合。

通常,存储过程用于修改不需要返回值的数据库数据或结构,例如删除,更新,删除等。或需要多个结果集的情况。另一方面,函数通常是为简单查询选择的。

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.