Nasza aplikacja musi równie dobrze współpracować z bazą danych Oracle lub Microsoft SQL Server. Aby to ułatwić, stworzyliśmy garść UDF w celu ujednolicenia naszej składni zapytań. Na przykład SQL Server ma GETDATE (), a Oracle ma SYSDATE. Pełnią tę samą funkcję, ale są różnymi słowami. Napisaliśmy opakowanie UDF o nazwie NOW () dla obu platform, które otacza odpowiednią składnię specyficzną dla platformy wspólną nazwą funkcji. Mamy inne takie funkcje, z których niektóre w zasadzie nic nie istnieją, ale istnieją wyłącznie w celu homogenizacji. Niestety ma to koszt dla SQL Server. Inline skalarne UDF sieją spustoszenie w wydajności i całkowicie wyłączają równoległość. Alternatywnie napisaliśmy funkcje asemblera CLR, aby osiągnąć te same cele. Kiedy wdrożyliśmy to na kliencie, zaczęli doświadczać częstych impasów. Ten konkretny klient korzysta z technik replikacji i wysokiej dostępności i zastanawiam się, czy nie zachodzi tutaj jakaś interakcja. Po prostu nie rozumiem, w jaki sposób wprowadzenie funkcji CLR spowodowałoby takie problemy. Dla odniesienia załączyłem oryginalną skalarną definicję UDF, a także zastępczą definicję CLR w C # i deklarację SQL dla niej. Mam także zakleszczenie XML, które mogę podać, jeśli to pomoże.
Oryginalny 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
Funkcja montażu CLR
[SqlFunction(IsDeterministic = true)]
public static string APAD(string value, string tableName, string columnName)
{
return value?.Trim();
}
Deklaracja programu SQL Server dla funkcji CLR
CREATE FUNCTION [fn].[APAD]
(
@Value NVARCHAR(4000),
@TableName NVARCHAR(4000),
@ColumnName NVARCHAR(4000)
) RETURNS NVARCHAR(4000)
AS
EXTERNAL NAME ASI.fn.APAD
GO