La nostra applicazione deve funzionare ugualmente bene con un database Oracle o un database Microsoft SQL Server. Per facilitare ciò, abbiamo creato una manciata di UDF per omogeneizzare la nostra sintassi delle query. Ad esempio, SQL Server ha GETDATE () e Oracle ha SYSDATE. Svolgono la stessa funzione ma sono parole diverse. Abbiamo scritto un wrapper UDF chiamato NOW () per entrambe le piattaforme che racchiude la sintassi specifica della piattaforma pertinente in un nome di funzione comune. Abbiamo altre funzioni del genere, alcune delle quali essenzialmente non fanno nulla ma esistono esclusivamente per motivi di omogeneizzazione. Sfortunatamente, questo ha un costo per SQL Server. Gli UDF scalari incorporati causano il caos delle prestazioni e disabilitano completamente il parallelismo. In alternativa, abbiamo scritto le funzioni di assemblaggio CLR per raggiungere gli stessi obiettivi. Quando lo abbiamo distribuito su un client, hanno iniziato a riscontrare frequenti deadlock. Questo particolare client utilizza tecniche di replica e disponibilità elevata e mi chiedo se ci sia una sorta di interazione in corso qui. Non capisco come l'introduzione di una funzione CLR possa causare problemi come questo. Per riferimento, ho incluso la definizione UDF scalare originale nonché la definizione CLR sostitutiva in C # e la relativa dichiarazione SQL. Ho anche un deadlock XML che posso fornire se questo aiuta.
UDF originale
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
Funzione di assemblaggio CLR
[SqlFunction(IsDeterministic = true)]
public static string APAD(string value, string tableName, string columnName)
{
return value?.Trim();
}
Dichiarazione di SQL Server per la funzione CLR
CREATE FUNCTION [fn].[APAD]
(
@Value NVARCHAR(4000),
@TableName NVARCHAR(4000),
@ColumnName NVARCHAR(4000)
) RETURNS NVARCHAR(4000)
AS
EXTERNAL NAME ASI.fn.APAD
GO