SQL Server中用户定义的函数有什么需求?

rin*_*esh 1 sql sql-server user-defined-functions

SQL Server中用户定义函数的确切需求是什么?

我们可以使用功能完成的所有事情都可以由存储过程完成,那么为什么要引入用户定义的功能呢?

我知道存储过程和函数之间的区别,但是没有一个可以澄清我的问题,而且我找不到函数可以执行的任何操作而存储过程无法做到的任何事情。

功能仅仅是为了更好的可维护性和理解性,还是我缺少某些东西?

Dai*_*Dai 7

我们可以使用函数完成的所有事情都可以由存储过程本身完成,

这是错误的。

  • 存储过程无法重组或内联(例如a VIEW或表值函数可以-并且SQL Server 2017 现在也可以内联标量函数)。
  • 数据库引擎不能证明存储过程是“安全的”(因为存储过程可以执行DML / DDL操作,而UDF仅可以执行只读操作)。
  • 存储过程不能用于对标量值执行操作。

你可以争论,一切你可以将使用UDF而没有UDF可以做一个查询中这样做-这在技术上是真实的(因为存储过程是图灵完备),但它好像是说我们不需要for,while,try/catch,using或asyncC#中的代码,因为对每个人来说肯定if并且goto足够好!

代码质量,可维护性和运行时性能很重要-适当地使用UDF不仅会带来美观的查询,而且由于内联,重组,对表达式树进行修剪等操作也会带来更好的性能。

此外,当所有很酷的孩子都在使用Entity Framework时,今天谁在使用存储过程?:D

脚注

我想详细说明一下:

存储过程不能用于对标量值执行操作。

尽管存储过程确实具有返回值和输出参数-它们的分类仍然与真正的UDF不同,因为存储过程返回值只能是一个int值(它们比POSIX / Win32更接近程序退出代码)实际返回值)和存储过程输出参数不能在另一个查询中使用,除非您使用CURSOR或Dynamic SQL(注入)进行难看的修改。

  • @ZLK但是,您不能在基于集合的操作中使用存储过程,这对UDF来说是一个巨大的收获。 (2认同)

mar*_*c_s 5

除了 @Dai 已经提到的所有要点之外:我使用标量函数INT从相当大的 XML 列中“提取”某些位和片段作为原子值(例如等),并使用标量函数定义计算列(基于该 XML 列)。

这是您不能使用存储过程做的另一件事 - 使用函数定义计算列的值(或定义“常规”列的检查或默认约束)。