Поделиться через


Скалярные функции среды CLR

Скалярная функция (SVF) возвращает одно значение, например строку, целое число или битовое значение. Вы можете создавать скалярные определяемые пользователем функции в управляемом коде с помощью любого языка программирования .NET Framework. Эти функции доступны для Transact-SQL или другого управляемого кода. Сведения о преимуществах интеграции СРЕДЫ CLR и выборе между управляемым кодом и Transact-SQL см. в разделе "Обзор интеграции СРЕДЫ CLR".

Требования к функциям СРЕДЫ CLR Scalar-Valued

Скалярные функции .NET Framework реализуются в виде методов класса в сборке .NET Framework. Входные параметры и тип, возвращаемые из SVF, могут быть любым из скалярных типов данных, поддерживаемых SQL Server, за исключением varchar, , , imagentextchartexttimestamprowversiontableили .cursor SVFS должны обеспечить соответствие между типом данных SQL Server и возвращаемым типом данных метода реализации. Дополнительные сведения о преобразованиях типов см. в разделе "Сопоставление данных параметров CLR".

При реализации SVF .NET Framework на языке .NET Framework можно указать пользовательский атрибут, SqlFunction чтобы включить дополнительные сведения о функции. Атрибут SqlFunction указывает, обращается ли функция к данным или изменяет данные, если он детерминирован, и если функция включает операции с плавающей запятой.

Скалярные определяемые пользователем функции могут быть детерминированными или недетерминированными. Детерминированная функция всегда возвращает тот же результат при вызове с определенным набором входных параметров. Недетерминированная функция может возвращать различные результаты при вызове с определенным набором входных параметров.

Замечание

Не помечайте функцию как детерминированную, если функция не всегда создает одинаковые выходные значения, учитывая те же входные значения и то же состояние базы данных. Не следует определять функцию как детерминированную, если в действительности она таковой не является. Это может привести к искажению индексированных представлений и вычисляемых столбцов. Вы помечаете функцию как детерминированную, установив для свойства IsDeterministic значение true.

параметры Table-Valued

Возвращающие табличное значение параметры — это определяемые пользователем табличные типы, которые передаются в процедуру или функцию, предоставляя эффективный способ передачи на сервер нескольких строк данных. TvPs предоставляют аналогичные функциональные возможности для массивов параметров, но обеспечивают большую гибкость и более тесную интеграцию с Transact-SQL. Они также обеспечивают возможность повышения производительности. Кроме того, возвращающие табличное значение параметры способствуют сокращению циклов приема-передачи данных с сервера и на сервер. Вместо того чтобы отправлять на сервер несколько запросов (как в случае списка скалярных параметров), данные можно отправить в виде возвращающего табличное значение параметра. Определяемый пользователем тип таблицы не может передаваться в качестве табличного параметра или возвращаться из управляемой хранимой процедуры или функции, выполняемой в процессе SQL Server. Дополнительные сведения о tvPs см. в разделе "Использование параметров Table-Valued (ядро СУБД)".

Пример функции CLR Scalar-Valued

Вот простой SVF, который обращается к данным и возвращает целочисленное значение:

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();  
        }  
    }  
}  
Imports Microsoft.SqlServer.Server  
Imports System.Data.SqlClient  
  
Public Class T  
    <SqlFunction(DataAccess:=DataAccessKind.Read)> _  
    Public Shared Function ReturnOrderCount() As Integer  
        Using conn As New SqlConnection("context connection=true")  
            conn.Open()  
            Dim cmd As New SqlCommand("SELECT COUNT(*) AS 'Order Count' FROM SalesOrderHeader", conn)  
            Return CType(cmd.ExecuteScalar(), Integer)  
        End Using  
    End Function  
End Class  

Первая строка кода ссылается на Microsoft.SqlServer.Server для доступа к атрибутам и System.Data.SqlClient для доступа к пространству имен ADO.NET. (Это пространство имен содержит SqlClient, поставщик данных .NET Framework для SQL Server.)

Затем функция получает SqlFunction настраиваемый атрибут, который находится в пространстве имен Microsoft.SqlServer.Server. Пользовательский атрибут указывает, используется ли определяемая пользователем функция (UDF) внутрипроцессным поставщиком для чтения данных с сервера. SQL Server не разрешает пользователям обновлять, вставлять или удалять данные. SQL Server может оптимизировать выполнение UDF, который не использует поставщик в процессе. Это означает, что для параметра DataAccessKind задано значение DataAccessKind.None. На следующей строке целевой метод определяется как public static (или на языке Visual Basic .NET — shared).

Затем класс SqlContext, расположенный в пространстве имен Microsoft.SqlServer.Server, может получить доступ к объекту SqlCommand с подключением к экземпляру SQL Server, который уже настроен. Хотя здесь не используется, текущий контекст транзакции также доступен через интерфейс программирования приложения System.Transactions (API).

Большинство строк кода в теле функции должны выглядеть знакомы с разработчиками, которые написали клиентские приложения, использующие типы, найденные в System.Data.SqlClient пространстве имен.

[C#]

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();  
}    

[Visual Basic]

Using conn As New SqlConnection("context connection=true")  
   conn.Open()  
   Dim cmd As New SqlCommand( _  
        "SELECT COUNT(*) AS 'Order Count' FROM SalesOrderHeader", conn)  
   Return CType(cmd.ExecuteScalar(), Integer)  
End Using  

Соответствующий текст команды указывается путем инициализации объекта SqlCommand. В предыдущем примере число строк в таблице SalesOrderHeader. Затем вызывается метод ExecuteScalar объекта cmd. Возвращает значение типа int на основе запроса. Наконец происходит возврат сведений о количестве заказов в вызывающий код.

После сохранения в файле с именем FirstUdf.cs этот код можно скомпилировать в сборку следующим образом:

[C#]

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

[Visual Basic]

vbc.exe /t:library /out:FirstUdf.dll FirstUdf.vb  

Замечание

/t:library указывает, что результатом компиляции должна быть библиотека, а не исполняемый объект. Исполняемые файлы нельзя зарегистрировать в SQL Server.

Замечание

Объекты базы данных Visual C++, скомпилированные с /clr:pure ним, не поддерживаются для выполнения в SQL Server. В частности, такими объектами базы данных являются скалярные функции.

Запрос Transact-SQL и пример вызова для регистрации сборки и UDF:

CREATE ASSEMBLY FirstUdf FROM 'FirstUdf.dll';  
GO  
  
CREATE FUNCTION CountSalesOrderHeader() RETURNS INT   
AS EXTERNAL NAME FirstUdf.T.ReturnOrderCount;   
GO  
  
SELECT dbo.CountSalesOrderHeader();  
GO  
  

Обратите внимание, что имя функции, предоставляемое в Transact-SQL, не обязательно соответствует имени целевого общедоступного статического метода.

См. также

Сопоставление данных параметров CLR
Общие сведения о настраиваемых атрибутах интеграции СРЕДЫ CLR
Определяемые пользователем функции
Доступ к данным из объектов базы данных CLR