什么时候使用存储过程/用户定义函数?

DAN*_*Fan 4 postgresql stored-procedures functions

我对 SP(存储过程)和 UDF(用户定义函数)的使用感到困惑。通常,也可以在数据库之外的程序中编写代码。

是否有任何一般建议来决定何时使用它们?

Erw*_*ter 15

Postgres 11 或更新版本

也可以开始和结束事务的SQL 过程(“存储过程”):

但是,交易块中不允许的命令(还)不能被包含在内。重要示例CREATE DATABASECREATE INDEX CONCURRENTLYVACUUM

但是,当使用INOUT参数创建时,过程只能返回单个结果行。Postgres 14 或更高版本也允许OUT参数。

Postgres 10 或以上(原始答案)

严格来说,没有“存储过程”。只是功能,几乎但不完全相同。最重要的是,函数总是在事务内运行,这对于锁管理、捕获错误或不能在事务上下文中运行的命令很重要(见上文)。有关的:

与将所有原始数据检索到您的应用程序中并在那里进行计算相比,在 SQL 中处理数据具有主要优势:

相同的原则可以应用于无法在单个语句中完成的更大操作,即使在(数据修改)CTE 中使用“链式”命令时也不适用:

根据用例的不同,一个函数的性能可能会更好,而且通常更方便——尤其是当多个应用程序访问同一个数据库时。您必须选择一种服务器端语言,最常见的是 SQL 或 PL/pgSQL:

在存在竞争性并发事务(多用户环境)时要简短。只将需要原子化的相同功能放入相同的功能中。如果可能,请避免使用许多锁的长事务。锁只在事务结束时释放。长事务可能会停止并发访问,甚至导致死锁(由 Postgres 自动检测并解决,通过为一个或多个竞争事务引发错误,然后回滚)......

如果您避免这些反模式,服务器端函数可能是一个很好的工具。出于某些目的,您无论如何都必须使用函数,例如触发器函数。