Udostępnij za pośrednictwem


Funkcje skalarne CLR

Dotyczy:programu SQL Server

Funkcja skalarna (SVF) zwraca pojedynczą wartość, taką jak ciąg, liczba całkowita lub wartość bitowa. Funkcje zdefiniowane przez użytkownika można tworzyć w kodzie zarządzanym przy użyciu dowolnego języka programowania .NET Framework. Te funkcje są dostępne dla Transact-SQL lub innego kodu zarządzanego. Aby uzyskać informacje o zaletach integracji środowiska uruchomieniowego języka wspólnego (CLR) i wybieraniu między kodem zarządzanym a językiem Transact-SQL, zobacz omówienie integracji środowiska CLR.

Wymagania dotyczące funkcji skalarnych CLR

Pliki SVFs programu .NET Framework są implementowane jako metody w klasie w zestawie .NET Framework. Parametry wejściowe i typ zwracany z formatu SVF mogą być dowolnymi typami danych skalarnych obsługiwanymi przez program SQL Server. z wyjątkiem varchar, char, rowversion, tekst, ntext, obrazu, sygnatury czasowej, tabelilub kursora . Pliki SVFs muszą zapewnić dopasowanie między typem danych programu SQL Server a zwracanym typem danych metody implementacji. Aby uzyskać więcej informacji na temat konwersji typów, zobacz mapowania danych parametrów CLR.

Podczas implementowania formatu SVF programu .NET Framework w języku .NET Framework można określić SqlFunction atrybut niestandardowy, aby uwzględnić dodatkowe informacje o funkcji. Atrybut SqlFunction wskazuje, czy funkcja uzyskuje dostęp do danych lub modyfikuje je, jeśli jest deterministyczna, a funkcja obejmuje operacje zmiennoprzecinkowe.

Funkcje zdefiniowane przez użytkownika z wartością skalarną mogą być deterministyczne lub niedeterministyczne. Funkcja deterministyczna zawsze zwraca ten sam wynik, gdy jest wywoływany z określonym zestawem parametrów wejściowych. Funkcja niedeterministyczna może zwracać różne wyniki, gdy jest wywoływana z określonym zestawem parametrów wejściowych.

Nuta

Nie oznaczaj funkcji jako deterministycznej, jeśli funkcja nie zawsze generuje te same wartości wyjściowe, biorąc pod uwagę te same wartości wejściowe i ten sam stan bazy danych. Oznaczanie funkcji jako deterministycznej, gdy funkcja nie jest naprawdę deterministyczna, może spowodować uszkodzenie indeksowanych widoków i obliczonych kolumn. Funkcję oznaczysz jako deterministyczną, ustawiając właściwość IsDeterministic na true.

Parametry wartości tabeli

Parametry tabeli (TVP), typy tabel zdefiniowane przez użytkownika, które są przekazywane do procedury lub funkcji, zapewniają wydajny sposób przekazywania wielu wierszy danych do serwera. Dostawcy usług telewizyjnych zapewniają podobną funkcjonalność do tablic parametrów, ale zapewniają większą elastyczność i ściślejszą integrację z językiem Transact-SQL. Zapewniają one również potencjał lepszej wydajności.

Telewizory pomagają również zmniejszyć liczbę rund na serwer. Zamiast wysyłać wiele żądań do serwera, takich jak lista parametrów skalarnych, dane mogą być wysyłane do serwera jako tvp. Nie można przekazać typu tabeli zdefiniowanego przez użytkownika jako parametru o wartości tabeli lub być zwracany z zarządzanej procedury składowanej lub funkcji wykonywanej w procesie programu SQL Server. Aby uzyskać więcej informacji o programach TVP, zobacz Use table-valued parameters (Database Engine).

Przykład funkcji skalarnej CLR

Oto prosty format SVF, który uzyskuje dostęp do danych i zwraca wartość całkowitą:

using Microsoft.SqlServer.Server;
using System.Data.SqlClient;

public class T
{
    [SqlFunction(DataAccess = DataAccessKind.Read)]
    public static int ReturnOrderCount()
    {
        using (SqlConnection conn
            = new SqlConnection("context connection=true"))
        {
            conn.Open();
            SqlCommand cmd = new SqlCommand(
                "SELECT COUNT(*) AS 'Order Count' FROM SalesOrderHeader", conn);
            return (int)cmd.ExecuteScalar();
        }
    }
}

Pierwszy wiersz odwołania kodu Microsoft.SqlServer.Server w celu uzyskania dostępu do atrybutów i System.Data.SqlClient w celu uzyskania dostępu do przestrzeni nazw ADO.NET. (Ta przestrzeń nazw zawiera SqlClient, dostawcę danych programu .NET Framework dla programu SQL Server).

Następnie funkcja odbiera atrybut niestandardowy SqlFunction, który znajduje się w przestrzeni nazw Microsoft.SqlServer.Server. Atrybut niestandardowy wskazuje, czy funkcja zdefiniowana przez użytkownika (UDF) używa dostawcy w procesie do odczytywania danych na serwerze. Program SQL Server nie zezwala na aktualizowanie, wstawianie lub usuwanie danych przez użytkownika. Program SQL Server może zoptymalizować wykonywanie funkcji zdefiniowanej przez użytkownika, która nie korzysta z dostawcy przetwarzania. Jest to wskazane przez ustawienie DataAccessKind na wartość DataAccessKind.None. W następnym wierszu metoda docelowa jest publiczną statyczną (udostępnioną w programie Visual Basic .NET).

Klasa SqlContext znajdująca się w przestrzeni nazw Microsoft.SqlServer.Server może następnie uzyskać dostęp do obiektu SqlCommand z połączeniem z już skonfigurowanym wystąpieniem programu SQL Server. Chociaż nie jest używany tutaj, bieżący kontekst transakcji jest również dostępny za pośrednictwem interfejsu programowania aplikacji (API) System.Transactions.

Większość wierszy kodu w treści funkcji powinna wyglądać znajomo deweloperom, którzy piszą aplikacje klienckie korzystające z typów znalezionych w przestrzeni nazw System.Data.SqlClient.

using(SqlConnection conn = new SqlConnection("context connection=true"))
{
   conn.Open();
   SqlCommand cmd = new SqlCommand(
        "SELECT COUNT(*) AS 'Order Count' FROM SalesOrderHeader", conn);
   return (int) cmd.ExecuteScalar();
}

Odpowiedni tekst polecenia jest określony przez zainicjowanie obiektu SqlCommand. W poprzednim przykładzie liczba wierszy w tabeli SalesOrderHeader. Następnie wywoływana jest metoda ExecuteScalar obiektu cmd. Zwraca wartość typu int na podstawie zapytania. Na koniec liczba zamówień jest zwracana do elementu wywołującego.

Jeśli ten kod zostanie zapisany w pliku o nazwie FirstUdf.cs, można go skompilować w następujący sposób:

csc.exe /t:library /out:FirstUdf.dll FirstUdf.cs

/t:library wskazuje, że powinna zostać utworzona biblioteka, a nie plik wykonywalny. Nie można zarejestrować plików wykonywalnych w programie SQL Server.

Obiekty bazy danych Visual C++ skompilowane przy użyciu /clr:pure nie są obsługiwane do wykonywania w programie SQL Server. Na przykład takie obiekty bazy danych obejmują funkcje skalarne.

Zapytanie Transact-SQL i przykładowe wywołanie do zarejestrowania zestawu i funkcji zdefiniowanej przez użytkownika są następujące:

CREATE ASSEMBLY FirstUdf
    FROM 'FirstUdf.dll';
GO

CREATE FUNCTION CountSalesOrderHeader()
RETURNS INT
AS EXTERNAL NAME FirstUdf.T.ReturnOrderCount;
GO

SELECT dbo.CountSalesOrderHeader();
GO

Nazwa funkcji uwidoczniona w Transact-SQL nie musi być zgodna z nazwą docelowej publicznej metody statycznej.