CLR-skalare Funktionen
Gilt für:SQL Server
Eine skalare Funktion (SVF) gibt einen einzelnen Wert zurück, z. B. eine Zeichenfolge, eine ganze Zahl oder einen Bitwert. Sie können skalare benutzerdefinierte Funktionen in verwaltetem Code mithilfe einer beliebigen .NET Framework-Programmiersprache erstellen. Auf diese Funktionen kann über Transact-SQL oder anderen verwalteten Code zugegriffen werden. Informationen zu den Vorteilen der ClR-Integration (Common Language Runtime) und der Auswahl zwischen verwaltetem Code und Transact-SQL finden Sie unter CLR-Integrationsübersicht.
Anforderungen für clR-skalare Funktionen
.NET Framework-Skalarwertfunktionen werden als Methoden einer Klasse in einer .NET Framework-Assembly implementiert. Die Eingabeparameter und der von einem SVF zurückgegebene Typ können beliebige skalare Datentypen sein, die von SQL Server unterstützt werden. außer varchar, char, rowversion, text, ntext, image, timestamp, table, or cursor. SVFs müssen eine Übereinstimmung zwischen dem SQL Server-Datentyp und dem Rückgabedatentyp der Implementierungsmethode sicherstellen. Weitere Informationen zu Typkonvertierungen finden Sie unter Map CLR-Parameterdaten.
Wenn Sie ein .NET Framework SVF in einer .NET Framework-Sprache implementieren, können Sie das benutzerdefinierte Attribut SqlFunction
angeben, um zusätzliche Informationen zur Funktion einzuschließen. Das attribut SqlFunction
gibt an, ob die Funktion auf Daten zugreift oder ändert, wenn sie deterministisch ist und ob die Funktion Gleitkommavorgänge umfasst.
Skalare benutzerdefinierte Funktionen können deterministisch oder nicht deterministisch sein. Eine deterministische Funktion gibt immer dasselbe Ergebnis zurück, wenn sie mit einem bestimmten Satz von Eingabeparametern aufgerufen wird. Eine nicht deterministische Funktion gibt möglicherweise unterschiedliche Ergebnisse zurück, wenn sie mit einem bestimmten Satz von Eingabeparametern aufgerufen wird.
Hinweis
Markieren Sie eine Funktion nicht als deterministisch, wenn die Funktion nicht immer dieselben Ausgabewerte erzeugt, wobei dieselben Eingabewerte und derselbe Datenbankstatus angegeben sind. Das Markieren einer Funktion als deterministisch, wenn die Funktion nicht wirklich deterministisch ist, kann zu beschädigten indizierten Ansichten und berechneten Spalten führen. Sie markieren eine Funktion als deterministisch, indem Sie die eigenschaft IsDeterministic
auf "true" festlegen.
Parameter mit Tabellenwert
Tabellenwertparameter (Table Valued Parameters, TVPs), benutzerdefinierte Tabellentypen, die an eine Prozedur oder Funktion übergeben werden, bieten eine effiziente Methode zum Übergeben mehrerer Datenzeilen an den Server. TVPs bieten ähnliche Funktionen wie Parameterarrays, bieten jedoch größere Flexibilität und engere Integration in Transact-SQL. Außerdem verfügen sie auch über ein besseres Leistungspotenzial.
TVPs helfen auch, die Anzahl von Roundtrips zum Server zu reduzieren. Anstatt mehrere Anforderungen an den Server zu senden, z. B. mit einer Liste von skalaren Parametern, können Daten als TVP an den Server gesendet werden. Ein benutzerdefinierter Tabellentyp kann nicht als Tabellenwertparameter übergeben oder von einer verwalteten gespeicherten Prozedur oder Funktion zurückgegeben werden, die im SQL Server-Prozess ausgeführt wird. Weitere Informationen zu TVPs finden Sie unter Verwenden von Tabellenwertparametern (Datenbankmodul).
Beispiel für eine CLR-Skalarwertfunktion
Hier ist ein einfacher SVF, der auf Daten zugreift und einen ganzzahligen Wert zurückgibt:
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();
}
}
}
Die erste Codezeile verweist Microsoft.SqlServer.Server
auf Attribute und System.Data.SqlClient
, um auf den ADO.NET Namespace zuzugreifen. (Dieser Namespace enthält SqlClient
, den .NET Framework-Datenanbieter für SQL Server.)
Als Nächstes empfängt die Funktion das SqlFunction
benutzerdefinierte Attribut, das im Microsoft.SqlServer.Server
-Namespace gefunden wird. Das benutzerdefinierte Attribut gibt an, ob die benutzerdefinierte Funktion (UDF) den prozessinternen Anbieter verwendet, um Daten im Server zu lesen. SQL Server lässt UDFs nicht zu, Daten zu aktualisieren, einzufügen oder zu löschen. SQL Server kann die Ausführung einer UDF optimieren, die den In-Process-Anbieter nicht verwendet. Dies wird durch Festlegen DataAccessKind
auf DataAccessKind.None
angegeben. Die Zielmethode in der nächsten Zeile ist eine öffentliche statische Methode (shared in Visual Basic .NET).
Die SqlContext
-Klasse, die sich im Microsoft.SqlServer.Server
Namespace befindet, kann dann auf ein SqlCommand
-Objekt mit einer Verbindung mit der bereits eingerichteten SQL Server-Instanz zugreifen. Obwohl hier nicht verwendet wird, ist der aktuelle Transaktionskontext auch über die System.Transactions
Anwendungsprogrammierschnittstelle (APPLICATION Programming Interface, API) verfügbar.
Die meisten Codezeilen im Funktionstext sollten Entwicklern vertraut sein, die Clientanwendungen schreiben, die die im System.Data.SqlClient
-Namespace gefundenen Typen verwenden.
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();
}
Der entsprechende Befehlstext wird durch Initialisieren des SqlCommand
-Objekts angegeben. Im vorherigen Beispiel wird die Anzahl der Zeilen in der Tabelle SalesOrderHeader
gezählt. Als Nächstes wird die ExecuteScalar
Methode des cmd
-Objekts aufgerufen. Dadurch wird ein Wert vom Typ "int " basierend auf der Abfrage zurückgegeben. Abschließend wird die Anzahl der Bestellungen an den Aufrufer zurückgegeben.
Wenn dieser Code in einer Datei namens FirstUdf.cs gespeichert wird, kann er wie folgt als Assembly kompiliert werden:
csc.exe /t:library /out:FirstUdf.dll FirstUdf.cs
/t:library
gibt an, dass eine Bibliothek und keine ausführbare Datei erzeugt werden soll. Ausführbare Dateien können nicht in SQL Server registriert werden.
Visual C++-Datenbankobjekte, die mit /clr:pure
kompiliert wurden, werden für die Ausführung auf SQL Server nicht unterstützt. Zu solchen Datenbankobjekten gehören beispielsweise Skalarwertfunktionen.
Die Transact-SQL-Abfrage und ein Beispielaufruf zum Registrieren der Assembly und der UDF sind:
CREATE ASSEMBLY FirstUdf
FROM 'FirstUdf.dll';
GO
CREATE FUNCTION CountSalesOrderHeader()
RETURNS INT
AS EXTERNAL NAME FirstUdf.T.ReturnOrderCount;
GO
SELECT dbo.CountSalesOrderHeader();
GO
Der Funktionsname, der in Transact-SQL verfügbar gemacht wird, muss nicht mit dem Namen der öffentlichen Zielmethode übereinstimmen.