为什么SQL Server UDF如此有限?
从for为什么SQL Server UDF如此有限?,sql,sql-server,user-defined-functions,Sql,Sql Server,User Defined Functions,从for创建函数中: 用户定义的函数不能用于执行修改数据库状态的操作。 我的问题很简单-为什么 是的,修改数据的UDF可能有潜在的不必要的副作用。 是的,如果一个UDF被调用了数千次,则会涉及开销 但这就是设计和测试的全部要点——确保在部署之前解决这些问题。那么,为什么数据库供应商坚持对开发人员施加这些人为的限制呢?本质上只能用作select语句的包装器的语言构造有什么意义 这个问题的原因如下:我正在编写一个函数来返回某个唯一整数ID的GUID。如果已经为该ID分配了GUID,我只需返回它;否则
创建函数中
:
用户定义的函数不能用于执行修改数据库状态的操作。
我的问题很简单-为什么
是的,修改数据的UDF可能有潜在的不必要的副作用。是的,如果一个UDF被调用了数千次,则会涉及开销 但这就是设计和测试的全部要点——确保在部署之前解决这些问题。那么,为什么数据库供应商坚持对开发人员施加这些人为的限制呢?本质上只能用作
select
语句的包装器的语言构造有什么意义
这个问题的原因如下:我正在编写一个函数来返回某个唯一整数ID的GUID。如果已经为该ID分配了GUID,我只需返回它;否则,我想生成一个新的GUID,将其存储到表中,然后返回新生成的GUID。(是的,这听起来很冗长,可能很疯狂,但当你把数据发送给另一家开发公司时,如果他们认为他们的设计是上帝传下来的,无法改进,那么微笑、点头并按他们的要求去做就更容易了)
我知道我可以使用带有输出参数的存储过程来实现相同的结果,但是我必须声明一个新变量来保存存储过程的结果。不仅如此,我还必须将我的简单的
select
转换成一个while循环,插入到一个临时表中,并为该循环的每次迭代调用存储过程。通常最好将可用的工具看作一个谱,从视图、通过UDF到存储过程。在一端(视图),您有很多限制,但这意味着优化器实际上可以“看穿”代码并做出明智的选择。另一方面(存储过程),您有很大的灵活性,但由于您有这样的自由度,您会失去一些功能(例如,因为您可以从存储过程返回多个结果集,您会失去将其作为更大查询的一部分“组合”的能力)
UDF处于中间位置—您可以做的比在视图中做的更多(例如,多个语句),但您没有存储过程那么大的灵活性。通过放弃这种自由,它允许将输出作为更大查询的一部分进行组合。例如,通过没有副作用,您可以保证UDF应用于哪个行顺序并不重要。如果您可能有副作用,优化器可能必须提供订购保证。我理解您的问题,我想,但从您的评论中可以看出: 我想从my_表中选择my_udf(my_变量),其中,
my_udf
选择或创建它返回的值
因此,您需要一个选择
,它(可能)修改数据。你能单独看一下这个句子,告诉我它读起来很好吗我当然不能
阅读您对实际需要做什么的描述:
我正在编写一个函数来返回
特定唯一整数ID的GUID。
如果已为分配GUID
我只是把它还给你;否则
我想生成一个新的GUID存储
将其放入表中,并返回
新生成的GUID
我知道我可以使用存储的
将输出参数设置为
达到同样的结果,但我
必须声明一个新变量才能
保留存储过程的结果。不仅
然后,我必须转换我的简单
选择插入的while循环
进入临时表,并调用
每次迭代的存储过程
循环
从最后一句话来看,您似乎必须一次处理多行,因此,如果一个
INSERT
,为那些还没有GUID的ID插入GUID,然后一个SELECT
,返回(现在)存在的所有GUID,怎么样?有时如果您无法实现您提出的解决方案,这可能表明您的解决方案不是最优的
使用这样的语句
INSERT INTO IntGuids(IntValue, GuidValue)
SELECT MyIntValues.IntValue, NEWID()
FROM MyIntValues
LEFT OUTER JOIN IntGuids ON MyIntValues.IntValue = IntGuids.IntValue
WHERE IntGuids.IntValue IS NULL
在1语句中创建需要的所有GUID。无需为每个值选择+插入。如果需要修改数据库状态,为什么不直接使用存储过程呢??UDF用于快速计算、查找或返回单个值——这就是它们的全部用途。他们做得很好,因为我想做一些类似于从my_表中选择my_udf(my_变量)的事情,其中,
my_udf
选择或创建它返回的值(如我在文章中解释的)。使用存储过程来获得相同的结果会使代码大10倍左右。