有副作用的标准SQL函数吗?


11

SQL标准是否定义了具有副作用的函数?

例如,当您执行以下操作时,它们是否具有用于写入文件 *或更新表中某些列中的值的功能?

SELECT myfunction(params...);

我有时见过这些,但是我很好奇SQL标准是否也这样做。


*这不是专门针对PostgreSQL的问题。我仅使用在PostgreSQL中看到的副作用示例。


在不同的平台上,功能有很大的不同,但是可以,例如,Oracle中有相当标准的(即Oracle提供的)附加功能,用于发送电子邮件。而且SQL Server中有不确定的功能,例如NEWID和RAND,SQL Server中的功能也可以称为扩展过程。
Cade Roux

3
如果问题是“ SQL标准是否包括具有副作用的函数 ”,我认为答案是否定的。如果问题是“ SQL标准是否允许编写具有副作用的函数 ”,那么我认为答案是肯定的。
a_horse_with_no_name

@a_horse_with_no_name,谢谢。我的问题是前者,关于风格和惯例。
tinlyx

Answers:


18

您在这里有几个不同的问题。

问:什么是ANSI标准SQL函数?

ANSI标准函数是AVG,COUNT,MIN,MAX之类的东西。它们已包含在1992年ANSI标准中,但这简直是枯燥乏味的阅读。

问:ANSI标准SQL函数是否会更改数据库中的数据?

否。您可以使用它们来更改数据-例如,我可以说:

INSERT INTO dbo.MyReport SELECT MAX(SalespersonRevenue) FROM dbo.Sales

但就其本身而言,仅使用AVG,COUNT,MIN,MAX等不应该永久更改数据库中的数据。

问:ANSI标准是否允许我编写自己的函数?

是的,但是确切的实现因供应商而异。您编写的函数可能符合ANSI语言标准,但是在函数内部进行的操作却令人生畏,例如产生副作用。

  • 在讨论预期行为时,有可能获得跨平台的答案。
  • 在讨论副作用时,事实并非如此。

问:我可以创建自己的函数来写入数据吗?

为什么可以,如果您有创造力。我是Microsoft SQL Server专家,所以我将重点介绍该平台。联机丛书的功能页显示

用户定义的函数不能用于执行修改数据库状态的操作。

我对此说:

你不是我的老爸

因此,这就是我违反规则的方式。警告:随之而来的是非常糟糕的主意。

  • 在您的函数中,查询专门为此目的而创建的新表,然后创建一些东西来监视表中的select语句,然后触发操作(扩展事件,审核或Profiler跟踪)。您可以将Rube Goldberg的各种装置连接在一起,以根据这些select语句执行工作。
  • 在该函数中,调用CLR代码-heck,甚至可以调用Web服务。该Web服务可以很好地将数据推回到您自己的数据库中。
  • 在函数中,调用xp_cmdshell并通过命令提示符执行某些操作。(评论中的HT @AaronBertrand。)

所有这些示例在性能和事务一致性方面都存在巨大的缺陷。您只是问理论上是否可以完成,答案是肯定的。我永远不会在自己的代码中使用其中任何一个-我退后一步,问:“我在这里要实现的业务目标是什么,有没有办法可以实现性能和事务一致性? ?如果您需要有关这些方面的具体建议,请问一个单独的有关具体问题的Stack问题。


谢谢。如果没有SQL标准,PSM是否允许函数或过程具有副作用?
蒂姆(Tim)


-3

关于SQL Server,我只能说肯定的话,看来这在所有数据库实现中都不一致。但是在SQL Server中,函数可能不会产生副作用。这是一条我一直试图绕开而又没有成功的硬性规定。

如果您从一般意义上考虑函数,则有一些SQL模块允许副作用(例如存储过程),而用户定义的函数则不允许。

俗话说“聪明的解决方案无法扩展”,这在Microsoft产品中尤其如此。在MS SQL Server的早期版本中,我已经看到了许多巧妙的解决方法,但由于MS将它们添加为真正的功能,因此在更高版本中已经过时了。

老实说,那些从未成为功能的功能,因为它们从根本上破坏了T-SQL开发的某些方面,因此从未成为功能。功能的副作用就是其中之一。


评论不作进一步讨论;此对话已转移至聊天
保罗·怀特9
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.