RECEIVE (Transact-SQL)

Aplica-se a:SQL ServerInstância Gerenciada de SQL do Azure

Recupera uma ou mais mensagens de uma fila. Dependendo da configuração de retenção da fila, essa instrução remove as mensagens da fila ou atualiza o status da mensagem na fila.

Convenções de sintaxe de Transact-SQL

Sintaxe

[ WAITFOR ( ]  
    RECEIVE [ TOP ( n ) ]   
        <column_specifier> [ ,...n ]  
        FROM <queue>  
        [ INTO table_variable ]  
        [ WHERE {  conversation_handle = conversation_handle  
                 | conversation_group_id = conversation_group_id } ]  
[ ) ] [ , TIMEOUT timeout ]  
[ ; ]  
  
<column_specifier> ::=  
{    *   
  |  { column_name | [ ] expression } [ [ AS ] column_alias ]  
}     [ ,...n ]   
  
<queue> ::=  
{ database_name.schema_name.queue_name | schema_name.queue_name | queue_name }

Observação

Para exibir a sintaxe do Transact-SQL para o SQL Server 2014 (12.x) e versões anteriores, confira a Documentação das versões anteriores.

Argumentos

WAITFOR

Especifica que a instrução RECEIVE aguardará a chegada de uma mensagem na fila, se não houver nenhuma mensagem no momento.

TOP( n )

Especifica o número máximo de mensagens a serem retornadas. Se essa cláusula não estiver especificada, todas as mensagens que atenderem aos critérios da instrução serão retornadas.

column_specifier

*
Especifica que o conjunto de resultados contém todas as colunas na fila.

column_name
O nome de uma coluna a ser incluído no conjunto de resultados.

expressão
Um nome de coluna, constante, função ou qualquer combinação de nomes de coluna, constantes e funções conectadas por um operador.

column_alias
Um nome alternativo para substituir o nome da coluna no conjunto de resultados.

FROM

Especifica a fila que contém as mensagens a serem recuperadas.

database_name
O nome do banco de dados que contém a fila da qual receber mensagens. Quando nenhum database name é fornecido, o padrão é o banco de dados atual.

schema_name
O nome do esquema que possui a fila da qual receber mensagens. Quando nenhum schema name é fornecido, o padrão é o nome de esquema padrão do usuário atual.

queue_name
O nome da fila da qual receber mensagens.

INTO table_variable

Especifica a variável de tabela na qual a instrução RECEIVE coloca mensagens. A variável de tabela deve ter o mesmo número de colunas que as mensagens. O tipo de dados de cada coluna na variável de tabela deve poder ser convertido implicitamente no tipo de dados da coluna correspondente nas mensagens. Se INTO não estiver especificado, as mensagens serão retornadas como um conjunto de resultados.

WHERE

Especifica a conversa ou grupo de conversa das mensagens recebidas. Se omitido, as mensagens serão retornadas do próximo grupo de conversa disponível.

conversation_handle = conversation_handle
Especifica a conversa para mensagens recebidas. O identificador de conversa fornecido deve ser um identificador exclusivo ou um tipo conversível em identificador exclusivo.

conversation_group_id = conversation_group_id
Especifica o grupo de conversa das mensagens recebidas. A conversation group ID fornecida deve ser um uniqueidentifier ou um tipo que possa ser convertido em uniqueidentifier.

TIMEOUT timeout

Especifica o período de tempo, em milissegundos, durante o qual a instrução aguarda uma mensagem. Essa cláusula pode ser usada apenas com a cláusula WAITFOR. Se essa cláusula não for especificada ou o tempo limite for -1, o tempo de espera será ilimitado. Se o tempo limite expirar, RECEIVE retornará um conjunto de resultados vazio.

Comentários

Importante

Se a instrução RECEIVE não for a primeira instrução em um lote ou procedimento armazenado, a instrução anterior deverá ser encerrada com um ponto-e-vírgula (;).

A instrução RECEIVE lê mensagens de uma fila e retorna um conjunto de resultados. O conjunto de resultados consiste em zero ou mais linhas, cada uma das quais contêm uma mensagem. Se a instrução INTO não for usada e column_specifier não atribuir os valores a variáveis locais, a instrução retornará um conjunto de resultados ao programa de chamada.

As mensagens retornadas pela instrução RECEIVE podem ser de tipos de mensagem diferentes. Os aplicativos podem usar a coluna message_type_name para rotear cada mensagem para código que controla o tipo de mensagem associado. Há duas classes de tipos de mensagem:

  • Tipos de mensagem definidos pelo aplicativo que são criados com a instrução CREATE MESSAGE TYPE. O conjunto de tipos de mensagem definidos pelo aplicativo que são permitidos em uma conversa são definidos pelo contrato do Service Broker especificado para a conversa.

  • Mensagens do sistema Service Broker que retornam informações de status ou de erro.

A instrução RECEIVE remove mensagens recebidas da fila a menos que a fila especifique retenção de mensagem. Quando a configuração de RETENTION da fila estiver ON, a instrução RECEIVE atualizará a coluna status para 0 e deixará as mensagens na fila. Quando uma transação que contém uma instrução RECEIVE é revertida, todas as alterações feitas na fila na transação também são revertidas, retornando mensagens para a fila.

Todas as mensagens retornadas por uma instrução RECEIVE pertencem ao mesmo grupo de conversa. A instrução RECEIVE bloqueia o grupo de conversa das mensagens retornadas até que a transação que contém a instrução termine. Uma instrução RECEIVE retorna mensagens que têm um status de 1. O conjunto de resultados retornado por uma instrução RECEIVE é ordenado implicitamente:

  • Se mensagens de vários grupos de conversa atenderem às condições da cláusula WHERE, a instrução RECEIVE retornará todas as mensagens de uma conversa antes de retornar mensagens para qualquer outra conversa. As conversas são processadas em ordem decrescente de nível de prioridade.

  • Para uma determinada conversa, uma instrução RECEIVE retorna mensagens em ordem crescente de message_sequence_number.

A cláusula WHERE da instrução RECEIVE pode conter apenas um critério de pesquisa que usa conversation_handle ou conversation_group_id. O critério de pesquisa não pode conter uma ou mais das outras colunas na fila. O conversation_handle ou conversation_group_id não pode ser uma expressão. O conjunto de mensagens retornado depende das condições especificadas na cláusula WHERE:

  • Se conversation_handle estiver especificado, RECEIVE retornará todas as mensagens da conversa especificada disponíveis na fila.

  • Se conversation_group_id estiver especificado, RECEIVE retornará todas as mensagens disponíveis na fila de qualquer conversa membro do grupo de conversa especificado.

  • Se não houver nenhuma cláusula WHERE, RECEIVE determinará qual grupo de conversa:

    • Tem uma ou mais mensagens na fila.

    • Não foi bloqueado por outra instrução RECEIVE.

    • Tem o nível de prioridade mais alto de todos os grupos de conversa que atendem a esses critérios.

    Em seguida, RECEIVE retornará todas as mensagens disponíveis na fila de qualquer conversa membro do grupo de conversa selecionado.

Se o identificador de conversa ou de grupo de conversa especificado na cláusula WHERE não existir ou não estiver associado à fila especificada, a instrução RECEIVE retornará um erro.

Se a fila especificada na instrução RECEIVE tiver o status de fila definido como OFF, a instrução falhará com um erro do Transact-SQL.

Quando a cláusula WAITFOR está especificada, a instrução aguarda o tempo limite especificado ou até que um conjunto de resultados esteja disponível. Se a fila for descartada ou se o status da fila estiver definido como OFF enquanto a instrução estiver aguardando, a instrução retornará um erro imediatamente. Se a instrução RECEIVE especificar um grupo de conversa ou identificador de conversa e o serviço dessa conversa for descartado ou movido para outra fila, a instrução RECEIVE relatará um erro do Transact-SQL.

RECEIVE não é válido em uma função definida pelo usuário.

A instrução RECEIVE não tem nenhuma prevenção de privação de prioridade. Se uma única instrução RECEIVE bloquear um grupo de conversa e recuperar muitas mensagens de conversa de baixa prioridade, nenhuma mensagem poderá ser recebida de conversas de alta prioridade no grupo. Para evitar isso, ao recuperar mensagens de conversas de baixa prioridade, use a cláusula TOP para limitar o número de mensagens recuperadas por cada instrução RECEIVE.

Colunas de fila

A tabela a seguir lista as colunas em uma fila.

Nome da coluna Tipo de dados Descrição
status tinyint Status da mensagem. Para mensagens retornadas pelo comando RECEIVE, o status é sempre 0. As mensagens na fila podem conter um dos seguintes valores:

0=Pronto
1=Mensagem recebida
2=Ainda não concluído
3=Mensagem enviada retida
priority tinyint O nível de prioridade de conversa aplicado à mensagem.
queuing_order bigint Número da ordem da mensagem na fila.
conversation_group_id uniqueidentifier O identificador do grupo de conversa a que pertence essa mensagem.
conversation_handle uniqueidentifier Tratamento para a conversa da qual essa mensagem faz parte.
message_sequence_number bigint Número de sequência da mensagem na conversa.
service_name nvarchar(128) O nome do serviço a que se destina a conversa.
service_id int Identificador de objeto do SQL Server do serviço para o qual a conversa é destinada.
service_contract_name nvarchar(128) O nome do contrato que a conversa segue.
service_contract_id int Identificador de objeto do SQL Server do contrato que a conversa segue.
message_type_name nvarchar(128) O nome do tipo de mensagem que descreve o formato da mensagem. Mensagens podem ser do tipo de mensagem de aplicativo ou mensagens de sistema de Agente.
message_type_id int Identificador de objeto do SQL Server do tipo de mensagem que descreve a mensagem.
validation nchar(2) Validação usada para a mensagem.

E=Vazio
N=Nenhum
X=XML
message_body varbinary(MAX) O conteúdo da mensagem.

Permissões

Para receber uma mensagem, o usuário atual deve ter permissão RECEIVE na fila.

Exemplos

R. Receber todas as colunas de todas as mensagens em um grupo de conversação

O exemplo a seguir recebe todas as mensagens disponíveis para o próximo grupo de conversa disponível da fila ExpenseQueue. A instrução retorna as mensagens como um conjunto de resultados.

RECEIVE * FROM ExpenseQueue ;  

B. Receber colunas especificadas para todas as mensagens em um grupo de conversação

O exemplo a seguir recebe todas as mensagens disponíveis para o próximo grupo de conversa disponível da fila ExpenseQueue. A instrução retorna as mensagens como um conjunto de resultados que contém as colunas conversation_handle, message_type_name e message_body.

RECEIVE conversation_handle, message_type_name, message_body  
FROM ExpenseQueue ;  

C. Receber a primeira mensagem disponível na fila

O exemplo a seguir recebe a primeira mensagem disponível da fila ExpenseQueue como um conjunto de resultados.

RECEIVE TOP (1) * FROM ExpenseQueue ;  

D. Receber todas as mensagens de uma conversa especificada

O exemplo a seguir recebe todas as mensagens disponíveis para a conversa especificada da fila ExpenseQueue como um conjunto de resultados.

DECLARE @conversation_handle UNIQUEIDENTIFIER ;  
  
SET @conversation_handle = <retrieve conversation from database> ;  
  
RECEIVE *  
FROM ExpenseQueue  
WHERE conversation_handle = @conversation_handle ;  

E. Receber mensagens para um grupo de conversação especificado

O exemplo a seguir recebe todas as mensagens disponíveis para o grupo de conversa especificado da fila ExpenseQueue como um conjunto de resultados.

DECLARE @conversation_group_id UNIQUEIDENTIFIER ;  
  
SET @conversation_group_id =   
    <retrieve conversation group ID from database> ;  
  
RECEIVE *  
FROM ExpenseQueue  
WHERE conversation_group_id = @conversation_group_id ;  

F. Receber em uma variável de tabela

O exemplo a seguir recebe todas as mensagens disponíveis para um grupo de conversa especificado da fila ExpenseQueue em uma variável de tabela.

DECLARE @conversation_group_id UNIQUEIDENTIFIER ;  
  
DECLARE @procTable TABLE(  
     service_instance_id UNIQUEIDENTIFIER,  
     handle UNIQUEIDENTIFIER,  
     message_sequence_number BIGINT,  
     service_name NVARCHAR(512),  
     service_contract_name NVARCHAR(256),  
     message_type_name NVARCHAR(256),  
     validation NCHAR,  
     message_body VARBINARY(MAX)) ;  
  
SET @conversation_group_id = <retrieve conversation group ID from database> ;  
  
RECEIVE TOP (1)  
    conversation_group_id,  
    conversation_handle,  
    message_sequence_number,  
    service_name,  
    service_contract_name,  
    message_type_name,  
    validation,  
    message_body  
FROM ExpenseQueue  
INTO @procTable  
WHERE conversation_group_id = @conversation_group_id ;  

G. Receber mensagens e aguardar indefinidamente

O exemplo a seguir recebe todas as mensagens disponíveis para o próximo grupo de conversa disponível na fila ExpenseQueue. A instrução aguardará até que pelo menos uma mensagem esteja disponível e retornará um conjunto de resultados que contém todas as colunas de mensagem.

WAITFOR (  
    RECEIVE *  
    FROM ExpenseQueue) ;  

H. Receber mensagens e aguardar um intervalo especificado

O exemplo a seguir recebe todas as mensagens disponíveis para o próximo grupo de conversa disponível na fila ExpenseQueue. A instrução aguarda durante 60 segundos ou até que pelo menos uma mensagem esteja disponível, o que ocorrer primeiro. A instrução retornará um conjunto de resultados que contém todas as colunas de mensagem se pelo menos uma mensagem estiver disponível. Caso contrário, a instrução retornará um conjunto de resultados vazio.

WAITFOR (  
    RECEIVE *  
    FROM ExpenseQueue ),  
TIMEOUT 60000 ;  

I. Receber mensagens, modificando o tipo de uma coluna

O exemplo a seguir recebe todas as mensagens disponíveis para o próximo grupo de conversa disponível na fila ExpenseQueue. Quando o tipo de mensagem declara que a mensagem contém um documento XML, a instrução converte o corpo da mensagem em XML.

WAITFOR (  
    RECEIVE message_type_name,  
        CASE  
            WHEN validation = 'X' THEN CAST(message_body as XML)  
            ELSE NULL  
         END AS message_body   
         FROM ExpenseQueue ),  
TIMEOUT 60000 ;  

J. Receber uma mensagem, extraindo dados do corpo da mensagem, recuperando o estado da conversa

O exemplo a seguir recebe a próxima mensagem disponível para o próximo grupo de conversa disponível na fila ExpenseQueue. Quando a mensagem é do tipo //Adventure-Works.com/Expenses/SubmitExpense, a instrução extrai a ID do funcionário e uma lista de itens do corpo da mensagem. A instrução também recupera o estado da conversa da tabela ConversationState.

WAITFOR(  
    RECEIVE   
    TOP(1)  
      message_type_name,  
      COALESCE(  
           (SELECT TOP(1) ConversationState  
            FROM CurrentConversations AS cc  
            WHERE cc.ConversationHandle = conversation_handle),  
           'NEW')  
      AS ConversationState,  
      COALESCE(  
          (SELECT TOP(1) ErrorCount  
           FROM CurrentConversations AS cc  
           WHERE cc.ConversationHandle = conversation_handle),   
           0)  
      AS ConversationErrors,  
      CASE WHEN message_type_name = N'//Adventure-Works.com/Expenses/SubmitExpense'  
          THEN CAST(message_body AS XML).value(  
                'declare namespace rpt = "https://Adventure-Works.com/schemas/expenseReport"  
                   (/rpt:ExpenseReport/rpt:EmployeeID)[1]', 'nvarchar(20)')  
         ELSE NULL  
      END AS EmployeeID,  
      CASE WHEN message_type_name = N'//Adventure-Works.com/Expenses/SubmitExpense'  
          THEN CAST(message_body AS XML).query(  
                'declare namespace rpt = "https://Adventure-Works.com/schemas/expenseReport"   
                     /rpt:ExpenseReport/rpt:ItemDetail')  
          ELSE NULL  
      END AS ItemList  
    FROM ExpenseQueue   
), TIMEOUT 60000 ;