RECEIVE (Transact-SQL)

Platí na:SQL ServerAzureSQL Managed Instance

Získá jednu nebo více zpráv z fronty. V závislosti na nastavení uchování fronty buď zprávu z fronty odstraní, nebo se její stav aktualizuje.

Transact-SQL konvence syntaxe

Syntax

[ 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 }

Arguments

WAITFOR

Specifikuje, že RECEIVE příkaz čeká na příchod zprávy do fronty, pokud aktuálně žádné zprávy nejsou přítomny.

TOP( n )

Určuje maximální počet zpráv, které mají být vráceny. Pokud tato klauzule není specifikována, vrátí se všechny zprávy, které splňují kritéria příkazu.

column_specifier

*
Specifikuje, že výsledná množina obsahuje všechny sloupce ve frontě.

column_name
Název sloupce, který se má zahrnout do výsledné množiny.

expression
Název sloupce, konstanta, funkce nebo jakákoli kombinace názvů sloupců, konstant a funkcí spojených operátorem.

column_alias
Alternativní název nahrazující název sloupce ve výsledné množině.

FROM

Specifikuje frontu, která obsahuje zprávy k načtení.

database_name
Název databáze, která obsahuje frontu pro přijímání zpráv. Pokud není zadán žádný název databáze , výchozí je aktuální databáze.

schema_name
Název schématu, které vlastní frontu pro přijímání zpráv. Pokud není uvedeno žádné jméno schématu , výchozí je pro aktuálního uživatele výchozí schéma.

queue_name
Název fronty, ze které se přijímají zprávy.

DO table_variable

Specifikuje tabulkovou proměnnou, do které zprávy umisťují RECEIVE . Proměnná tabulky musí mít stejný počet sloupců jako ve zprávách. Datový typ každého sloupce v tabulkové proměnné musí být implicitně převoditelný na datový typ příslušného sloupce ve zprávách. Pokud INTO není specifikováno, zprávy se vrátí jako výsledná množina.

WHERE

Specifikuje konverzaci nebo skupinu pro přijaté zprávy. Pokud je vynecháno, vrací zprávy z další dostupné konverzační skupiny.

conversation_handle = conversation_handle
Specifikuje konverzaci pro přijaté zprávy. Připsaný konverzační handle musí být uniqueidentifier, nebo typ, který lze převést na uniqueidentifier.

conversation_group_id = conversation_group_id
Specifikuje skupinu konverzace pro přijaté zprávy. Poskytnuté ID skupiny konverzací musí být uniqueidentifier nebo typ převoditelný na uniqueidentifier.

TIMEOUT

Specifikuje dobu, po kterou příkaz čeká na zprávu v milisekundách. Tato klauzule může být použita pouze s klauzulí WAITFOR. Pokud tato klauzule není specifikována nebo je time-out , -1čekací doba je neomezená. Pokud vyprší časový limit, RECEIVE vrátí se prázdná množina výsledků.

Remarks

Important

Pokud RECEIVE příkaz není prvním příkazem v dávkové nebo uložené procedurě, musí být předchozí příkaz ukončen středníkem (;).

Příkaz RECEIVE čte zprávy z fronty a vrací výslednou množinu. Výsledná sada se skládá z nuly nebo více řádků, z nichž každý obsahuje jednu zprávu. Pokud není použita klauzule INTO a column_specifier nepřiřadí hodnoty lokálním proměnným, příkaz vrátí výslednou množinu volajícímu programu.

Zprávy, které příkaz vrací, RECEIVE mohou být různých typů zpráv. Aplikace mohou použít sloupec message_type_name k směrování každé zprávy do kódu, který zpracovává příslušný typ zprávy. Existují dvě třídy typů zpráv:

  • Aplikací definované typy zpráv, které byly vytvořeny pomocí příkazu CREATE MESSAGE TYPE . Sada aplikací definovaných typů zpráv, které jsou povoleny v konverzaci, je definována smlouvou Service Broker, která je pro konverzaci specifikována.

  • Systémové zprávy Service Broker, které vracejí informace o stavu nebo chybě.

Příkaz RECEIVE odebírá přijaté zprávy z fronty, pokud fronta nespecifikuje uchovávání zpráv. Když je nastavení RETENTION pro frontu ZAPNUTO, příkaz aktualizuje RECEIVEstatus sloupec na a 0 zprávy ve frontě ponechá. Když se transakce obsahující RECEIVE příkaz vrátí zpět, všechny změny ve frontě v transakci jsou také vráceny zpět a zprávy se vracejí do fronty.

Všechny zprávy vrácené příkazem RECEIVE patří do stejné konverzační skupiny. Příkaz RECEIVE uzamkne konverzační skupinu pro zprávy, které jsou vráceny, dokud transakce obsahující příkaz nedokončí. RECEIVE Příkaz vrací zprávy, které mají z status1. Množina výsledků vrácená příkazem RECEIVE je implicitně uspořádána:

  • Pokud zprávy z více konverzací splňují podmínky klauzule WHERE, příkaz vrátí všechny zprávy z jedné konverzace dříve, RECEIVE než vrátí zprávy pro jakoukoli jinou konverzaci. Konverzace jsou zpracovávány v sestupném pořadí podle úrovně priorit.

  • Pro daný rozhovor RECEIVE příkaz vrací zprávy vzestupně message_sequence_number .

Klauzule RECEIVE WHERE ve výroku může obsahovat pouze jednu podmínku vyhledávání, která používá buď conversation_handle nebo conversation_group_id. Podmínka vyhledávání nesmí obsahovat jeden nebo více dalších sloupců ve frontě. Nebo conversation_handleconversation_group_id nemůže být výraz. Množina vrácených zpráv závisí na podmínkách specifikovaných v klauzuli WHERE:

  • Pokud je conversation_handle specifikováno, vrátí všechny zprávy z dané konverzace, RECEIVE které jsou dostupné ve frontě.

  • Pokud je conversation_group_id specifikováno, vrátí všechny zprávy dostupné ve frontě z jakéhokoli konverzačního systému, RECEIVE který je členem dané skupiny.

  • Pokud neexistuje klauzule WHERE, určuje, RECEIVE která konverzační skupina:

    • Má jednu nebo více zpráv ve frontě.

    • Nebylo to uzamčeno dalším RECEIVE prohlášením.

    • Má nejvyšší prioritu ze všech konverzačních skupin, které splňují tato kritéria.

    RECEIVE poté vrátí všechny zprávy dostupné ve frontě z jakéhokoli konverzačního rozhovoru, který je členem vybrané skupiny.

Pokud konverzační handle nebo identifikátor konverzační skupiny uvedený v klauzuli WHERE neexistuje nebo není přiřazen k dané frontě, RECEIVE příkaz vrátí chybu.

Pokud má fronta specifikovaná ve příkazu RECEIVE stav fronty nastavený na VYPNUTO, příkaz selže s chybou Transact-SQL.

Když je specifikována klauzule WAITFOR, příkaz čeká na stanovený časový limit nebo dokud nebude k dispozici množina výsledků. Pokud je fronta ukončena nebo je stav fronty nastaven na VYPNUTO, zatímco příkaz čeká, příkaz okamžitě vrátí chybu. Pokud RECEIVE příkaz specifikuje konverzační skupinu nebo konverzační handle a služba pro tuto konverzaci je zrušena nebo přesunuta do jiné fronty, hlásí RECEIVE Transact-SQL chybu.

RECEIVE není platná v uživatelsky definované funkci.

Prohlášení RECEIVE nemá žádnou prioritu před hladověním. Pokud jedno RECEIVE prohlášení uzamkne konverzační skupinu a získá mnoho zpráv z nízkoprioritních konverzací, nelze přijmout žádné zprávy z vysoce prioritních konverzací ve skupině. Aby se tomu zabránilo, při načítání zpráv z konverzací s nízkou prioritou použijte klauzuli TOP k omezení počtu zpráv získaných každým RECEIVE příkazem.

Sloupce fronty

Následující tabulka uvádí sloupce ve frontě:

Název sloupce Datový typ Description
status tinyint Stav zprávy Pro zprávy vrácené příkazem RECEIVE je stav vždy 0. Zprávy ve frontě mohou obsahovat jednu z následujících hodnot:

0=Připraven
1=Přijatá zpráva
2=Ještě není dokončeno
3=Zpráva zachovaná
priority tinyint Úroveň priority konverzace, která je na zprávu aplikována.
queuing_order bigint Číslo pořadí zprávy ve frontě.
conversation_group_id uniqueidentifier Identifikátor konverzační skupiny, do které tato zpráva patří.
conversation_handle uniqueidentifier Připojte se k konverzaci, které je tato zpráva součástí.
message_sequence_number bigint Pořadové číslo zprávy v konverzaci.
service_name nvarchar(128) Název služby, se kterou se konverzace vede.
service_id int SQL Server identifikátor objektu služby, se kterou je konverzace vedena.
service_contract_name nvarchar(128) Název smlouvy, po které následuje konverzace.
service_contract_id int SQL Server identifikátor objektu smlouvy, po které konverzace probíhá.
message_type_name nvarchar(128) Název typu zprávy, který popisuje formát zprávy. Zprávy mohou být buď typu aplikačních zpráv, nebo zprávy systému Broker.
message_type_id int SQL Server identifikátor objektu typu zprávy, který zprávu popisuje.
validation nchar(2) Validace použitá pro zprávu.

E=Prázdné
N=Žádné
X=XML
message_body varbinary(MAX) Obsah zprávy

Permissions

Pro přijetí zprávy musí mít aktuální uživatel RECEIVE oprávnění k frontě.

Examples

A. Přijímejte všechny sloupce ke všem zprávám ve skupině konverzace

Následující příklad přijímá všechny dostupné zprávy pro další dostupnou konverzační skupinu z fronty ExpenseQueue . Příkaz vrací zprávy jako výslednou množinu.

RECEIVE * FROM ExpenseQueue ;  

B. Přijímání specifikovaných sloupců pro všechny zprávy ve skupině konverzace

Následující příklad přijímá všechny dostupné zprávy pro další dostupnou konverzační skupinu z fronty ExpenseQueue . Příkaz vrací conversation_handlezprávy jako výslednou množinu obsahující sloupce , message_type_name, a message_body.

RECEIVE conversation_handle, message_type_name, message_body  
FROM ExpenseQueue ;  

C. Přijměte první dostupnou zprávu ve frontě

Následující příklad přijímá první dostupnou zprávu z fronty ExpenseQueue jako výslednou množinu.

RECEIVE TOP (1) * FROM ExpenseQueue ;  

D. Přijímejte všechny zprávy pro určený rozhovor

Následující příklad přijímá všechny dostupné zprávy pro zadaný konverzační systém z fronty ExpenseQueue jako výslednou sadu.

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

E. Přijímání zpráv pro určenou konverzační skupinu

Následující příklad přijímá všechny dostupné zprávy pro zadanou konverzační skupinu z fronty ExpenseQueue jako výslednou sadu.

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. Přijmi do tabulkové proměnné

Následující příklad přijímá všechny dostupné zprávy pro specifikovanou konverzační skupinu z fronty ExpenseQueue do tabulkové proměnné.

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. Přijímání zpráv a čekání neomezeně dlouho

Následující příklad přijímá všechny dostupné zprávy pro další dostupnou konverzační skupinu ve frontě ExpenseQueue . Příkaz počká, dokud nebude dostupná alespoň jedna zpráva, poté vrátí výslednou sadu obsahující všechny sloupce zpráv.

WAITFOR (  
    RECEIVE *  
    FROM ExpenseQueue) ;  

H. Přijímání zpráv a čekání na stanovený interval

Následující příklad přijímá všechny dostupné zprávy pro další dostupnou konverzační skupinu ve frontě ExpenseQueue . Příkaz čeká 60 sekund nebo dokud nebude k dispozici alespoň jedna zpráva, podle toho, co nastane dříve. Příkaz vrací výslednou sadu, která obsahuje všechny sloupce zpráv, pokud je k dispozici alespoň jedna zpráva. Jinak příkaz vrací prázdnou množinu výsledků.

WAITFOR (  
    RECEIVE *  
    FROM ExpenseQueue ),  
TIMEOUT 60000 ;  

I. Přijímání zpráv, úprava typu sloupce

Následující příklad přijímá všechny dostupné zprávy pro další dostupnou konverzační skupinu ve frontě ExpenseQueue . Když typ zprávy uvádí, že zpráva obsahuje XML dokument, příkaz převede tělo zprávy na 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. Přijmout zprávu, extrahovat data z těla zprávy, obnovit stav konverzace

Následující příklad přijímá další dostupnou zprávu pro další dostupnou konverzační skupinu ve frontě ExpenseQueue . Když je zpráva typu //Adventure-Works.com/Expenses/SubmitExpense, příkaz extrahuje ID zaměstnance a seznam položek z těla zprávy. Prohlášení také přináší stanovisko k rozhovoru ze stolu 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 ;