Objeto SqlPipe
Aplica-se:SQL Server
Nas versões anteriores do SQL Server, era comum gravar um procedimento armazenado (ou um procedimento armazenado estendido) que enviava resultados ou parâmetros de saída para o cliente de chamada.
Em um procedimento armazenado Transact-SQL, qualquer instrução SELECT
que retorna zero ou mais linhas envia os resultados para o "pipe" do chamador conectado.
Para objetos de banco de dados CLR (Common Language Runtime) em execução no SQL Server, você pode enviar resultados para o pipe conectado usando os métodos Send
do objeto SqlPipe
. Acesse a propriedade Pipe
do objeto SqlContext
para obter o objeto SqlPipe
. A classe SqlPipe
é conceitualmente semelhante à classe Response
encontrada em ASP.NET.
Para obter mais informações, consulte Microsoft.SqlServer.Server.SqlPipe.
Retornar mensagens e resultados tabulares
O objeto SqlPipe
tem um método Send
, que tem três sobrecargas. Eles são:
void Send(string message)
void Send(SqlDataReader reader)
void Send(SqlDataRecord record)
O método Send
envia dados diretamente para o cliente ou chamador. Geralmente, é o cliente que consome a saída do SqlPipe
, mas com procedimentos armazenados clr aninhados, o consumidor de saída também pode ser um procedimento armazenado. Por exemplo, Procedure1
chamadas SqlCommand.ExecuteReader()
com o texto de comando EXEC Procedure2
.
Procedure2
também é um procedimento armazenado gerenciado. Se Procedure2
agora chamar SqlPipe.Send(SqlDataRecord)
, a linha será enviada ao leitor em Procedure1
, não ao cliente.
O método Send
envia uma mensagem de cadeia de caracteres que aparece no cliente como uma mensagem de informação, equivalente a PRINT
no Transact-SQL. Ele também pode enviar um conjunto de resultados de linha única usando SqlDataRecord
ou um conjunto de resultados de várias linhas usando um SqlDataReader
.
O objeto SqlPipe
também tem um método ExecuteAndSend
. Esse método pode ser usado para executar um comando (passado como um objeto SqlCommand
) e enviar resultados diretamente de volta para o chamador. Se houver erros no comando que foi enviado, as exceções serão enviadas para o pipe e uma cópia será enviada para chamar o código gerenciado. Se o código de chamada não capturar a exceção, ele propagará a pilha para o código Transact-SQL e aparecerá na saída duas vezes. Se o código de chamada capturar a exceção, o consumidor de pipe ainda verá o erro, mas não há um erro duplicado.
Ele só pode usar um SqlCommand
associado à conexão de contexto; ele não pode usar um comando associado à conexão sem contexto.
Retornar conjuntos de resultados personalizados
Os procedimentos armazenados gerenciados podem enviar conjuntos de resultados que não vêm de um SqlDataReader
. O método SendResultsStart
, juntamente com SendResultsRow
e SendResultsEnd
, permite que os procedimentos armazenados enviem conjuntos de resultados personalizados para o cliente.
SendResultsStart
usa um SqlDataRecord
como entrada. Ele marca o começo de um conjunto de resultados e usa os metadados de registro para criar os metadados que descrevem o conjunto de resultados. Ele não envia o valor do registro com SendResultsStart
. Todas as linhas subsequentes, enviadas usando SendResultsRow
, devem corresponder a essa definição de metadados.
Depois de chamar o método SendResultsStart
, somente SendResultsRow
e SendResultsEnd
poderão ser chamados. Chamar qualquer outro método na mesma instância de SqlPipe
causa um InvalidOperationException
.
SendResultsEnd
define SqlPipe
de volta ao estado inicial no qual outros métodos podem ser chamados.
Exemplo
O procedimento armazenado uspGetProductLine
retorna o nome, o número do produto, a cor e o preço de lista de todos os produtos dentro de uma linha de produto especificada. Este procedimento armazenado aceita correspondências exatas para prodLine
.
using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
public partial class StoredProcedures
{
[Microsoft.SqlServer.Server.SqlProcedure]
public static void uspGetProductLine(SqlString prodLine)
{
// Connect through the context connection.
using (SqlConnection connection = new SqlConnection("context connection=true"))
{
connection.Open();
SqlCommand command = new SqlCommand(
"SELECT Name, ProductNumber, Color, ListPrice " +
"FROM Production.Product " +
"WHERE ProductLine = @prodLine;", connection);
command.Parameters.AddWithValue("@prodLine", prodLine);
try
{
// Execute the command and send the results to the caller.
SqlContext.Pipe.ExecuteAndSend(command);
}
catch (System.Data.SqlClient.SqlException ex)
{
// An error occurred executing the SQL command.
}
}
}
};
A instrução Transact-SQL a seguir executa o procedimento uspGetProduct
, que retorna uma lista de produtos de bicicleta de turismo.
EXECUTE uspGetProductLineVB 'T';