Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Uma SVF (função com valor escalar) retorna um único valor, como um valor de cadeia de caracteres, inteiro ou bit. Você pode criar funções definidas pelo usuário com valor escalar no código gerenciado usando qualquer linguagem de programação do .NET Framework. Essas funções podem ser acessadas pelo Transact-SQL ou outro código gerenciado. Para obter informações sobre as vantagens da integração clr e escolher entre código gerenciado e Transact-SQL, consulte Visão geral da integração clr.
Requisitos para clr Scalar-Valued functions
As SVFs do .NET Framework são implementadas como métodos em uma classe de um assembly do .NET Framework. Os parâmetros de entrada e o tipo retornado de um SVF podem ser qualquer um dos tipos de dados escalares compatíveis com o SQL Server, exceto varchar, , char, rowversion, text, ntext, , image, timestamptableou cursor. As SVFs devem garantir uma correspondência entre o tipo de dados do SQL Server e o tipo de dados de retorno do método de implementação. Para obter mais informações sobre conversões de tipo, consulte Mapeamento de dados de parâmetro CLR.
Ao implementar um SVF do .NET Framework em uma linguagem .NET Framework, o SqlFunction atributo personalizado pode ser especificado para incluir informações adicionais sobre a função. O SqlFunction atributo indica se a função acessa ou não os dados, se eles são determinísticos e se a função envolve operações de ponto flutuante.
As funções definidas pelo usuário com valor escalar podem ser determinísticas ou não determinísticas. Uma função determinística sempre retorna o mesmo resultado quando é chamada com um conjunto específico de parâmetros de entrada. Uma função não determinística pode retornar resultados diferentes quando é chamada com um conjunto específico de parâmetros de entrada.
Observação
Não marque uma função como determinística se a função nem sempre produzir os mesmos valores de saída, considerando os mesmos valores de entrada e o mesmo estado do banco de dados. A marcação de uma função como determinística, quando a função, de fato, não é pode resultar em exibições indexadas e colunas computadas danificadas. Você marca uma função como determinística definindo a propriedade IsDeterministic como true.
Parâmetros com valor de tabela
Os TVPs (parâmetros com valor de tabela), ou seja, tipos de tabela definidos pelo usuário transmitidos para um procedimento ou uma função, oferecem uma maneira eficiente de passar várias linhas de dados para o servidor. As TVPs fornecem funcionalidade semelhante às matrizes de parâmetros, mas oferecem maior flexibilidade e integração mais próxima com o Transact-SQL. Eles também fornecem o potencial para melhor desempenho. Os TVPs também ajudam a reduzir o número de viagens de ida e volta para o servidor. Em vez de enviar várias solicitações ao servidor, como com uma lista de parâmetros escalares, os dados podem ser enviados ao servidor como um TVP. Um tipo de tabela definido pelo usuário não pode ser passado como um parâmetro com valor de tabela para, ou ser retornado, um procedimento armazenado gerenciado ou uma função em execução no processo do SQL Server. Para obter mais informações sobre TVPs, consulte Use Table-Valued Parameters (Mecanismo de Banco de Dados).
Exemplo de uma função clr Scalar-Valued
Aqui está um SVF simples que acessa dados e retorna um valor inteiro:
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
A primeira linha de código faz referência Microsoft.SqlServer.Server acessar atributos e System.Data.SqlClient para acessar o namespace ADO.NET. (Esse namespace contém SqlClient, o Provedor de Dados do .NET Framework para SQL Server.)
Em seguida, a função recebe o atributo personalizado SqlFunction, que é encontrado no namespace Microsoft.SqlServer.Server. O atributo personalizado indica se a UDF (função definida pelo usuário) usa ou não o provedor em processo para ler dados no servidor. O SQL Server não permite que UDFs atualizem, insiram ou excluam dados. O SQL Server pode otimizar a execução de um UDF que não usa o provedor em processo. Isso é indicado definindo DataAccessKind como DataAccessKind.None. Na próxima linha, o método de destino é uma estática pública (compartilhada no Visual Basic .NET).
A classe SqlContext, localizada no namespace Microsoft.SqlServer.Server, pode acessar um objeto SqlCommand com uma conexão com a instância do SQL Server que já está configurada. Embora não seja usado aqui, o contexto de transação atual também está disponível por meio da API (interface de programação do aplicativo) System.Transactions.
A maioria das linhas de código no corpo da função deve parecer familiar para os desenvolvedores que escreveram aplicativos cliente que usam os tipos encontrados no System.Data.SqlClient namespace.
[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
O texto de comando apropriado é especificado inicializando o objeto SqlCommand. O exemplo anterior conta o número de linhas na tabela SalesOrderHeader. Em seguida, o método ExecuteScalar do objeto cmd é chamado. Isso retorna um valor de tipo int com base na consulta. Por fim, a contagem da ordem retorna ao chamador.
Caso seja salvo em um arquivo chamado FirstUdf.cs, esse código pode ser compilado como assembly da seguinte forma:
[C#]
csc.exe /t:library /out:FirstUdf.dll FirstUdf.cs
[Visual Basic]
vbc.exe /t:library /out:FirstUdf.dll FirstUdf.vb
Observação
/t:library indica que uma biblioteca, e não um executável, deve ser produzida. Executáveis não podem ser registrados no SQL Server.
Observação
Não há suporte para objetos de banco de dados do Visual C++ compilados /clr:pure para execução no SQL Server. Por exemplo, entre esses objetos de banco de dados estão funções de valor escalar.
A consulta Transact-SQL e uma invocação de exemplo para registrar o assembly e a UDF são:
CREATE ASSEMBLY FirstUdf FROM 'FirstUdf.dll';
GO
CREATE FUNCTION CountSalesOrderHeader() RETURNS INT
AS EXTERNAL NAME FirstUdf.T.ReturnOrderCount;
GO
SELECT dbo.CountSalesOrderHeader();
GO
Observe que o nome da função conforme exposto em Transact-SQL não precisa corresponder ao nome do método estático público de destino.
Consulte Também
Mapeamento de dados de parâmetro CLR
Visão geral dos atributos personalizados de integração clr
Funções definidas pelo usuário
Acesso a dados de objetos de banco de dados CLR