我们的应用程序需要与Oracle数据库或Microsoft SQL Server数据库同样良好地工作。为方便起见,我们创建了一些UDF以使查询语法同质。例如,SQL Server具有GETDATE(),而Oracle具有SYSDATE。它们执行相同的功能,但它们是不同的词。我们为两个平台编写了一个名为NOW()的包装UDF,该包装将相关的平台特定语法包装在一个通用函数名称中。我们还有其他这样的功能,其中一些功能实际上什么也不做,只是为了同质化而存在。不幸的是,这对于SQL Server是有成本的。内联标量UDF严重破坏性能,并完全禁用并行性。作为替代方案,我们编写了CLR汇编函数以实现相同的目标。当我们将其部署到客户端时,他们开始遇到频繁的死锁。这个特定的客户端正在使用复制和高可用性技术,我想知道这里是否存在某种交互。我只是不了解引入CLR函数将如何导致这样的问题。作为参考,我在C#中包含了原始的标量UDF定义以及替换的CLR定义,并为其提供了SQL声明。如果有帮助,我也可以提供死锁XML。
原始UDF
CREATE FUNCTION [fn].[APAD]
(
@Value VARCHAR(4000)
, @tablename VARCHAR(4000) = NULL
, @columnname VARCHAR(4000) = NULL
)
RETURNS VARCHAR(4000)
WITH SCHEMABINDING
AS
BEGIN
RETURN LTRIM(RTRIM(@Value))
END
GO
CLR组装功能
[SqlFunction(IsDeterministic = true)]
public static string APAD(string value, string tableName, string columnName)
{
return value?.Trim();
}
用于CLR功能的SQL Server声明
CREATE FUNCTION [fn].[APAD]
(
@Value NVARCHAR(4000),
@TableName NVARCHAR(4000),
@ColumnName NVARCHAR(4000)
) RETURNS NVARCHAR(4000)
AS
EXTERNAL NAME ASI.fn.APAD
GO
9
确定性标量CLR函数不应导致死锁。当然,可以读取数据库的CLR函数。您应该在问题中包括死锁XML。
—
David Browne-微软