RECEIVE (Transact-SQL)

Van toepassing op:SQL ServerAzure SQL Managed Instance

Haalt één of meer berichten op uit een wachtrij. Afhankelijk van de retentie-instelling voor de wachtrij verwijdert het het bericht uit de wachtrij of wordt de status van het bericht in de wachtrij bijgewerkt.

Transact-SQL syntaxis-conventies

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

Geeft aan dat de RECEIVE instructie wacht tot een bericht in de wachtrij arriveert, als er momenteel geen berichten aanwezig zijn.

TOP( n )

Specificeert het maximale aantal te retourneren berichten. Als deze clausule niet is gespecificeerd, worden alle berichten teruggegeven die aan de statementcriteria voldoen.

column_specifier

*
Geeft aan dat de resultaatset alle kolommen in de wachtrij bevat.

column_name
De naam van een kolom die in de resultaatset moet worden opgenomen.

expression
Een kolomnaam, constante, functie, of een willekeurige combinatie van kolomnamen, constanten en functies die door een operator verbonden zijn.

column_alias
Een alternatieve naam om de kolomnaam in de resultaatset te vervangen.

FROM

Specificeert de wachtrij die de berichten bevat die opgehaald moeten worden.

database_name
De naam van de database die de wachtrij bevat waaruit berichten worden ontvangen. Wanneer er geen databasenaam wordt opgegeven, wordt de huidige database standaard gebruikt.

schema_name
De naam van het schema dat de wachtrij bezit om berichten van te ontvangen. Wanneer er geen schemanaam wordt opgegeven, wordt het standaard gebruikt voor het standaardschema van de huidige gebruiker.

queue_name
De naam van de wachtrij waaruit berichten worden ontvangen.

IN table_variable

Specificeert de tabelvariabele waarin RECEIVE de berichten worden geplaatst. De tabelvariabele moet hetzelfde aantal kolommen hebben als in de berichten. Het datatype van elke kolom in de tabelvariabele moet impliciet omgezet kunnen worden naar het datatype van de overeenkomstige kolom in de berichten. Als INTO niet is gespecificeerd, worden de berichten teruggegeven als een resultaatset.

WHERE

Specificeert het gesprek of de gespreksgroep voor de ontvangen berichten. Als het wordt weggelaten, wordt bericht teruggegeven van de eerstvolgende beschikbare gespreksgroep.

conversation_handle = conversation_handle
Specificeert het gesprek voor ontvangen berichten. De verstrekte gesprekshandle moet een uniqueidentifier zijn, of een type dat omgezet kan worden in uniqueidentifier.

conversation_group_id = conversation_group_id
Specificeert de gespreksgroep voor ontvangen berichten. De gespreksgroep-ID die wordt opgegeven, moet een uniqueidentifier zijn, of een type dat converteerbaar is naar uniqueidentifier.

TIMEOUT timeout

Specificeert de tijd, in milliseconden, waarin de instructie op een bericht moet wachten. Deze clausule kan alleen worden gebruikt met de WAITFOR-clausule. Als deze clausule niet is gespecificeerd, of de time-out is -1, is de wachttijd onbeperkt. Als de time-out verloopt, RECEIVE geeft een lege resultaatset terug.

Remarks

Important

Als de RECEIVE uitspraak niet de eerste uitspraak is in een batch of opgeslagen procedure, moet de voorgaande uitspraak worden afgesloten met een puntkomma (;).

De RECEIVE instructie leest berichten uit een wachtrij en geeft een resultaatset terug. De resultaatset bestaat uit nul of meer rijen, waarvan elk één bericht bevat. Als de INTO-clausule niet wordt gebruikt en column_specifier de waarden niet aan lokale variabelen toewijst, geeft de instructie een resultaatset terug aan het aanroepende programma.

De berichten die door de stelling worden teruggestuurd, RECEIVE kunnen van verschillende berichttypes zijn. Applicaties kunnen de message_type_name kolom gebruiken om elk bericht te routeren naar code die het bijbehorende berichttype behandelt. Er zijn twee klassen berichttypen:

  • Applicatie-gedefinieerde berichttypes die zijn gemaakt met behulp van de CREATE MESSAGE TYPE instructie. De set applicatie-gedefinieerde berichttypes die in een gesprek zijn toegestaan, wordt bepaald door het Service Broker-contract dat voor het gesprek is gespecificeerd.

  • Service Broker-systeemberichten die status- of foutinformatie teruggeven.

De RECEIVE instructie verwijdert ontvangen berichten uit de wachtrij, tenzij de wachtrij het geheugenbehoud specificeert. Wanneer de RETENTION-instelling voor de wachtrij AAN staat, werkt de RECEIVE instructie de status kolom bij en 0 laat de berichten in de wachtrij staan. Wanneer een transactie die een RECEIVE instructie bevat terugrolt, worden alle wijzigingen in de wachtrij in de transactie ook teruggerold, waardoor berichten terugkeren naar de wachtrij.

Alle berichten die door een RECEIVE verklaring worden teruggestuurd, behoren tot dezelfde gespreksgroep. De RECEIVE instructie vergrendelt de gespreksgroep voor de berichten die worden teruggestuurd totdat de transactie met de instructie is afgerond. Een RECEIVE statement geeft berichten terug die een status van hebben 1. De resultaatset die door een RECEIVE uitspraak wordt teruggegeven, is impliciet geordend:

  • Als berichten van meerdere gesprekken voldoen aan de WHERE-clausulevoorwaarden, retourneert de RECEIVE instructie alle berichten van één gesprek voordat het berichten voor een ander gesprek teruggeeft. De gesprekken worden verwerkt in aflopende volgorde van prioriteitsniveau.

  • Voor een gegeven gesprek geeft een RECEIVE statement berichten terug in oplopende message_sequence_number volgorde.

De WHERE-clausule van de RECEIVE instructie kan slechts één zoekvoorwaarde bevatten die gebruikmaakt van ofwel conversation_handle of conversation_group_id. De zoekvoorwaarde kan niet één of meer van de andere kolommen in de wachtrij bevatten. De conversation_handle of conversation_group_id kan geen uitdrukking zijn. De verzameling berichten die worden teruggestuurd, hangt af van de voorwaarden die zijn gespecificeerd in de WHERE-clausule:

  • Als conversation_handle is gespecificeerd, RECEIVE retourneert alle berichten van het opgegeven gesprek die beschikbaar zijn in de wachtrij.

  • Als conversation_group_id is gespecificeerd, RECEIVE retourneert alle berichten die beschikbaar zijn in de wachtrij van elk gesprek dat lid is van de opgegeven gespreksgroep.

  • Als er geen WHERE-clausule is, bepaalt RECEIVE welke gespreksgroep:

    • Heeft één of meer berichten in de wachtrij.

    • Is niet vergrendeld door een andere RECEIVE verklaring.

    • Heeft het hoogste prioriteitsniveau van alle gespreksgroepen die aan deze criteria voldoen.

    RECEIVE vervolgens retourneert alle berichten die beschikbaar zijn in de wachtrij van elk gesprek dat lid is van de geselecteerde gespreksgroep.

Als de conversation handle of conversation group identifier gespecificeerd in de WHERE-clausule niet bestaat, of niet gekoppeld is aan de opgegeven wachtrij, geeft de RECEIVE instructie een foutmelding terug.

Als de wachtrij die in de RECEIVE instructie is gespecificeerd de wachtrijstatus op UIT heeft gezet, faalt de instructie met een Transact-SQL fout.

Wanneer de WAITFOR-clausule wordt gespecificeerd, wacht de instructie op de opgegeven time-out, of totdat er een resultaatset beschikbaar is. Als de wachtrij wordt verwijderd of de status van de wachtrij op UIT staat terwijl de instructie wacht, geeft de instructie onmiddellijk een foutmelding terug. Als de RECEIVE instructie een gespreksgroep of gesprekshandle specificeert en de service voor dat gesprek wordt verwijderd of naar een andere wachtrij wordt verplaatst, meldt de RECEIVE instructie een Transact-SQL fout.

RECEIVE is niet geldig in een door de gebruiker gedefinieerde functie.

De RECEIVE verklaring heeft geen prioriteit bij preventie van honger. Als één enkele RECEIVE verklaring een gespreksgroep vergrendelt en veel berichten ophaalt uit gesprekken met lage prioriteit, kunnen er geen berichten worden ontvangen van gesprekken met hoge prioriteit in de groep. Om dit te voorkomen, gebruik je bij het ophalen van berichten uit gesprekken met lage prioriteit de TOP-clausule om het aantal berichten dat door elke RECEIVE instructie wordt opgehaald te beperken.

Wachtrijkolommen

De volgende tabel geeft een overzicht van de kolommen in een wachtrij:

Kolomnaam Gegevenstype Description
status tinyint Status van het bericht. Voor berichten die door het RECEIVE commando worden teruggestuurd, is de status altijd 0. Berichten in de wachtrij kunnen een van de volgende waarden bevatten:

0=Klaar
1=Ontvangen bericht
2=Nog niet compleet
3=Verzonden bericht behouden
priority tinyint Het prioriteitsniveau van het gesprek dat aan het bericht wordt toegekend.
queuing_order bigint Bericht ordernummer in de wachtrij.
conversation_group_id uniqueidentifier Identifier voor de gespreksgroep waartoe dit bericht behoort.
conversation_handle uniqueidentifier Handle voor het gesprek waarvan dit bericht deel uitmaakt.
message_sequence_number bigint Volgnummer van het bericht in het gesprek.
service_name nvarchar(128) De naam van de dienst waaraan het gesprek gaat.
service_id int SQL Server objectidentificatie van de dienst waar het gesprek naartoe gaat.
service_contract_name nvarchar(128) De naam van het contract waarop het gesprek volgt.
service_contract_id int SQL Server objectidentificatie van het contract waarop het gesprek volgt.
message_type_name nvarchar(128) Naam van het berichttype dat het formaat van het bericht beschrijft. Berichten kunnen zowel toepassingsberichttypes als Broker-systeemberichten zijn.
message_type_id int SQL Server objectidentificatie van het berichttype dat het bericht beschrijft.
validation nchar(2) Validatie gebruikt voor het bericht.

E=Leeg
N=Geen
X=XML
message_body varbinary(MAX) Inhoud van het bericht.

Permissions

Om een bericht te ontvangen, moet de huidige gebruiker toestemming hebben RECEIVE voor de wachtrij.

Examples

A. Ontvang alle kolommen voor alle berichten in een gespreksgroep

Het volgende voorbeeld ontvangt alle beschikbare berichten voor de eerstvolgende beschikbare gespreksgroep uit de ExpenseQueue wachtrij. De instructie geeft de berichten terug als een resultaatset.

RECEIVE * FROM ExpenseQueue ;  

B. Ontvang gespecificeerde kolommen voor alle berichten in een gespreksgroep

Het volgende voorbeeld ontvangt alle beschikbare berichten voor de eerstvolgende beschikbare gespreksgroep uit de ExpenseQueue wachtrij. De instructie geeft de berichten terug als een resultaatset die de kolommen conversation_handle, message_type_name, en message_bodybevat.

RECEIVE conversation_handle, message_type_name, message_body  
FROM ExpenseQueue ;  

C. Ontvang het eerste beschikbare bericht in de wachtrij

Het volgende voorbeeld ontvangt het eerste beschikbare bericht uit de ExpenseQueue wachtrij als een resultaatset.

RECEIVE TOP (1) * FROM ExpenseQueue ;  

D. Ontvang alle berichten voor een gespecificeerd gesprek

Het volgende voorbeeld ontvangt alle beschikbare berichten voor het gespecificeerde gesprek uit de ExpenseQueue wachtrij als een resultaatset.

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

E. Ontvangen berichten voor een bepaalde gespreksgroep

Het volgende voorbeeld ontvangt alle beschikbare berichten voor de opgegeven gespreksgroep uit de ExpenseQueue wachtrij als een resultaatset.

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. Ontvang in een tabelvariabele

Het volgende voorbeeld ontvangt alle beschikbare berichten voor een gespecificeerde gespreksgroep van de ExpenseQueue wachtrij naar een tabelvariabele.

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. Berichten ontvangen en oneindig wachten

Het volgende voorbeeld ontvangt alle beschikbare berichten voor de volgende beschikbare gespreksgroep in de ExpenseQueue wachtrij. De instructie wacht tot er ten minste één bericht beschikbaar is en geeft vervolgens een resultaatset terug die alle berichtkolommen bevat.

WAITFOR (  
    RECEIVE *  
    FROM ExpenseQueue) ;  

H. Berichten ontvangen en wachten op een bepaald interval

Het volgende voorbeeld ontvangt alle beschikbare berichten voor de volgende beschikbare gespreksgroep in de ExpenseQueue wachtrij. De verklaring wacht 60 seconden of totdat er ten minste één bericht beschikbaar is, afhankelijk van wat het eerst gebeurt. De instructie geeft een resultaatset terug die alle berichtkolommen bevat als er ten minste één bericht beschikbaar is. Anders geeft de instructie een lege resultaatset terug.

WAITFOR (  
    RECEIVE *  
    FROM ExpenseQueue ),  
TIMEOUT 60000 ;  

I. Ontvangen berichten, waarbij het type van een kolom wordt aangepast

Het volgende voorbeeld ontvangt alle beschikbare berichten voor de volgende beschikbare gespreksgroep in de ExpenseQueue wachtrij. Wanneer het berichttype aangeeft dat het bericht een XML-document bevat, zet de instructie de berichttekst om naar 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. Ontvang een bericht, haal gegevens uit de berichtentekst, haal de conversatiestatus op

Het volgende voorbeeld ontvangt het volgende beschikbare bericht voor de volgende beschikbare gespreksgroep in de ExpenseQueue wachtrij. Wanneer het bericht van het type //Adventure-Works.com/Expenses/SubmitExpenseis, haalt de instructie de werknemers-ID en een lijst met items uit de berichttekst. De stelling haalt ook de toestand van het gesprek op uit de ConversationState tabel.

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 ;