Наше приложение должно одинаково хорошо работать с базой данных Oracle или базой данных Microsoft SQL Server. Чтобы облегчить это, мы создали несколько UDF для гомогенизации нашего синтаксиса запроса. Например, в SQL Server есть GETDATE (), а в Oracle - SYSDATE. Они выполняют одну и ту же функцию, но это разные слова. Мы написали UDF-оболочку с именем NOW () для обеих платформ, которая оборачивает специфический для конкретной платформы синтаксис в общее имя функции. У нас есть другие такие функции, некоторые из которых по сути ничего не делают, но существуют исключительно ради гомогенизации. К сожалению, это имеет цену для SQL Server. Встроенные скалярные UDF наносят ущерб производительности и полностью отключают параллелизм. В качестве альтернативы мы написали функции сборки CLR для достижения тех же целей. Когда мы развернули это на клиенте, они начали испытывать частые тупики. Этот конкретный клиент использует методы репликации и высокой доступности, и мне интересно, происходит ли какое-то взаимодействие здесь. Я просто не понимаю, как введение функции CLR может вызвать такие проблемы. Для справки я включил исходное скалярное определение UDF, а также определение CLR для замены в C # и объявление 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();
}
Декларация SQL Server для функции CLR
CREATE FUNCTION [fn].[APAD]
(
@Value NVARCHAR(4000),
@TableName NVARCHAR(4000),
@ColumnName NVARCHAR(4000)
) RETURNS NVARCHAR(4000)
AS
EXTERNAL NAME ASI.fn.APAD
GO