Nosso aplicativo precisa funcionar igualmente bem com um banco de dados Oracle ou Microsoft SQL Server. Para facilitar isso, criamos um punhado de UDFs para homogeneizar nossa sintaxe de consulta. Por exemplo, o SQL Server possui GETDATE () e o Oracle possui SYSDATE. Eles executam a mesma função, mas são palavras diferentes. Escrevemos um wrapper UDF chamado NOW () para ambas as plataformas que agrupa a sintaxe específica da plataforma relevante em um nome de função comum. Temos outras funções desse tipo, algumas das quais nada fazem senão que existem apenas em prol da homogeneização. Infelizmente, isso tem um custo para o SQL Server. UDFs escalares em linha causam estragos no desempenho e desabilitam completamente o paralelismo. Como alternativa, escrevemos funções de montagem CLR para atingir os mesmos objetivos. Quando implantamos isso em um cliente, eles começaram a enfrentar conflitos frequentes. Esse cliente em particular está usando técnicas de replicação e alta disponibilidade e estou me perguntando se há algum tipo de interação acontecendo aqui. Só não entendo como a introdução de uma função CLR causaria problemas como este. Para referência, incluí a definição UDF escalar original, bem como a definição CLR de substituição no C # e a declaração SQL. Também tenho XML de impasse que posso fornecer, se isso ajudar.
UDF original
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
Função de montagem CLR
[SqlFunction(IsDeterministic = true)]
public static string APAD(string value, string tableName, string columnName)
{
return value?.Trim();
}
Declaração do SQL Server para função CLR
CREATE FUNCTION [fn].[APAD]
(
@Value NVARCHAR(4000),
@TableName NVARCHAR(4000),
@ColumnName NVARCHAR(4000)
) RETURNS NVARCHAR(4000)
AS
EXTERNAL NAME ASI.fn.APAD
GO