来自create function
的{{3}}:
User-defined functions cannot be used to perform actions that modify the database state.
我的问题很简单 - 为什么?
是的,修改数据的UDF可能会产生潜在的不良副作用 是的,如果UDF被调用数千次,则会产生开销。
但这是设计和测试的全部要点 - 确保在部署之前解决这些问题。那么为什么数据库供应商坚持要对开发人员施加这些人为限制呢?语言构造的重点是什么,它基本上只能用作select
语句的包装器?
这个问题的原因如下:我正在编写一个函数来返回某个唯一整数ID的GUID。如果已经为该ID分配了GUID,我只需将其返回;否则我想生成一个新的GUID,将其存储到表中,并返回新生成的GUID。 (是的,这听起来很啰嗦,可能很疯狂,但是当你把数据发送到另一家开发公司时,他们认为他们的设计是由上帝传下来的,而且无法改进,只是微笑点头并做他们要求的事情更容易)。
我知道我可以使用带有输出参数的存储过程来实现相同的结果,但是我必须声明一个新变量来保存sproc的结果。不仅如此,我还必须将简单的select
转换为插入临时表的while循环,并在该循环的每次迭代中调用sproc。
答案 0 :(得分:2)
通常最好将可用工具视为一种频谱,从视图,UDF到存储过程。在一端(视图),您有很多限制,但这意味着优化器实际上可以“透视”代码并做出明智的选择。在另一端(存储过程),你有很多灵活性,但由于你有这样的自由,你失去了一些能力(例如,因为你可以从存储过程中返回多个结果集,你失去了“撰写”的能力它作为更大查询的一部分。)
UDF处于中间位置 - 您可以在视图中执行更多操作(例如,多个语句),但是您没有存储过程那么多的灵活性。通过放弃这种自由,它允许输出作为更大查询的一部分组成。如果没有副作用,您可以保证,例如,应用UDF的行顺序无关紧要。如果您可能有副作用,优化程序可能必须提供排序保证。
答案 1 :(得分:0)
我认为我理解你的问题,但是从你的评论中得到这个:
我想做
select my_udf(my_variable) from my_table
之类的事情,其中my_udf
选择或创建它返回的值
所以你想要select
(可能)修改数据。你能不能自己看一下这句话,告诉我那句话完全没问题? - 我当然不能。
阅读您对实际需要做的描述:
我正在写一个函数来返回一个 某个唯一整数ID的GUID。 如果已分配GUID 那个ID我只是归还它;除此以外 我想生成一个新的GUID,商店 进入一张桌子,并返回 新生成的GUID。
我知道我可以使用存储的 输出参数的过程 实现相同的结果,但后来我 必须声明一个新的变量 保持sproc的结果。不只 那个,然后我必须转换我的简单 选择插入的while循环 进入临时表,然后打电话给 每次迭代的sproc 循环。
从最后一句话看起来你必须一次处理很多行,那么单个INSERT
如何为那些尚未拥有它们的ID插入GUID,然后是一个SELECT
1}}返回(现在)存在的所有GUID?
答案 2 :(得分:0)
有时,如果您无法实现您提出的解决方案,则可能表明您的解决方案不是最佳解决方案。
使用这样的声明
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。无需为每个值选择SELECT + INSERT。