Partilhar via


Objeto SqlPipe

Aplica-se a:SQL Server

Em versões anteriores do SQL Server, era comum escrever um procedimento armazenado (ou um procedimento armazenado estendido) que enviava resultados ou parâmetros de saída para o cliente chamador.

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 resultados tabulares e mensagens

O objeto SqlPipe tem um método Send, que tem três sobrecargas. São eles:

  • void Send(string message)
  • void Send(SqlDataReader reader)
  • void Send(SqlDataRecord record)

O método Send envia dados diretamente para o cliente ou chamador. Normalmente, é 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 do comando EXEC Procedure2. Procedure2 também é um procedimento armazenado gerenciado. Se Procedure2 agora chama SqlPipe.Send(SqlDataRecord), a linha é enviada para o leitor em Procedure1, não para o cliente.

O método Send envia uma mensagem de cadeia de caracteres que aparece no cliente como uma mensagem informativa, equivalente a PRINT no Transact-SQL. Ele também pode enviar um conjunto de resultados de linha única usando SqlDataRecordou 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 enviado, 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 detetar a exceção, o consumidor de pipe ainda verá o erro, mas não há um erro duplicado.

Ele só pode tomar um SqlCommand que está associado à conexão de contexto; ele não pode aceitar 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 toma um SqlDataRecord como entrada. Ele marca o início de um conjunto de resultados e usa os metadados de registro para construir 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, apenas SendResultsRow e SendResultsEnd podem ser chamados. Chamar qualquer outro método na mesma instância de SqlPipe causa uma 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 tabela de todos os produtos dentro de uma linha de produtos 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';