Tsql 什么';当我们绕过SQL Server';UDF中副作用操作的限制?
今天,我使用这种方法取得了巨大成功,根据数据中的“测试”/“生产”标志,在同一数据库模式的多个实例中使用随机垃圾替换名称、保险号和地址 背景:尝试做什么Tsql 什么';当我们绕过SQL Server';UDF中副作用操作的限制?,tsql,Tsql,今天,我使用这种方法取得了巨大成功,根据数据中的“测试”/“生产”标志,在同一数据库模式的多个实例中使用随机垃圾替换名称、保险号和地址 背景:尝试做什么 CREATE FUNCTION dbo.FailsToCreate() RETURNS uniqueidentifier AS BEGIN RETURN NEWID() END 不可避免地以失败告终 Msg 443,16级,状态1,程序FailsToCreate,第6行[批次开始第27行] 在函数中使用副作用运算符“newid”无
CREATE FUNCTION dbo.FailsToCreate()
RETURNS uniqueidentifier
AS
BEGIN
RETURN NEWID()
END
不可避免地以失败告终
Msg 443,16级,状态1,程序FailsToCreate,第6行[批次开始第27行]
在函数中使用副作用运算符“newid”无效。
现在我们可以做个大坏蛋了
CREATE VIEW dbo.vwGuessWhat AS SELECT NEWID() Fooled
这让我们很惊讶地发现它可以与
CREATE FUNCTION dbo.SuddenlyWorks()
RETURNS uniqueidentifier
AS
BEGIN
RETURN (SELECT Fooled FROM vwGuessWhat)
END
他对后果保持沉默。它只列出了不能使用的函数,没有提到绕过限制的可能性
我是否可以安全地继续在生产代码中使用此方法,或者绕过SQL Server的验证是否存在导致其出现故障的危险?本身没有风险。您提供了一种有趣的方法来规避SQL函数的限制 另一方面,标量UDF的许多问题之一是它们破坏了并行性。换句话说,使用dbo.SuddenlyWorks()的查询将始终连续运行,即使使用Adam Machanic的make_parallel()或traceflag 8649
如果您想要一个并行计划,您需要使dbo.SuddenlyWorks()成为一个内联表值函数。文档中怎么说?为什么你会相信一个随机的人对官方文件的意见呢?他对后果保持沉默。它只列出了不能使用的函数,没有提到绕过限制的可能性。为什么你认为这个问题会吸引固执己见的答案?我希望看到确凿的事实,比如“在场景X中,它会因为Y而发生故障”。@dlatikay我实际上同意这是一个合理的问题;但是,我认为答案是“它没有定义,或者:它被定义为非法”(取决于您对它的解释)——唯一能够回答这个问题的人是SQL Server开发人员。无论哪种方式,我个人都不会在行为未定义或定义为非法的情况下使用。在这种情况下,您不是从UDF内部调用非确定性函数,而是从视图中选择一个值,这不是同一件事,即使视图提供了您想要的。我个人的意见(嗯,这似乎在某种程度上是基于观点的…):我会使用
视图方法。许多人这样做是为了创建一个随机数(例如,取NEWID()
的前4个字节,并将它们转换为INT
。这是因为重复调用RAND()
会返回所有调用的结果相同…)如果微软能修复这一问题,大量高效的代码将被破坏。。。