RECEIVE (Transact-SQL)

Dotyczy:SQL ServerAzure SQL Managed Instance

Pobiera jedną lub więcej wiadomości z kolejki. W zależności od ustawienia retencji dla kolejki, albo usuwa wiadomość z kolejki, albo aktualizuje status wiadomości w kolejce.

Transact-SQL konwencje składni

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

Określa, że RECEIVE polecenie czeka na przybycie wiadomości do kolejki, jeśli aktualnie nie ma żadnych komunikatów.

TOP( n )

Określa maksymalną liczbę zwróconych wiadomości. Jeśli ta klauzula nie jest określona, zwracane są wszystkie wiadomości spełniające kryteria polecenia.

column_specifier

*
Określa, że zbiór wyników zawiera wszystkie kolumny w kolejce.

column_name
Nazwa kolumny do uwzględnienia w zbiorze wyników.

expression
Nazwa kolumny, stała, funkcja lub dowolna kombinacja nazw kolumn, stałych i funkcji połączonych operatorem.

column_alias
Alternatywna nazwa zastępująca nazwę kolumny w zbiorze wyników.

FROM

Określa kolejkę, która zawiera wiadomości do pobrania.

database_name
Nazwa bazy danych, która zawiera kolejkę do odbierania wiadomości. Gdy nie podaje się nazwy bazy , domyślnie przyjmuje aktualną bazę danych.

schema_name
Nazwa schematu, który jest właścicielem kolejki do otrzymywania wiadomości. Gdy nie podaje się nazwy schematu , domyślnie przyjmuje schemat domyślny dla bieżącego użytkownika.

queue_name
Nazwa kolejki do odbierania wiadomości.

DO table_variable

Określa zmienną tabelową, w której RECEIVE umieszczają wiadomości. Zmienna tabelowa musi mieć tyle samo kolumn, ile znajduje się w komunikatach. Typ danych każdej kolumny zmiennej tabelowej musi być niejawnie konwertowalny na typ danych odpowiadającej kolumny w wiadomościach. Jeśli INTO nie jest określone, wiadomości zwracane są jako zbiór wyników.

WHERE

Określa rozmowę lub grupę konwersacyjną dla otrzymanych wiadomości. Jeśli zostanie pominięty, zwraca wiadomości z najbliższej dostępnej grupy konwersacyjnej.

conversation_handle = conversation_handle
Określa rozmowę dla otrzymanych wiadomości. Podana konwersacja musi być unikalnym identyfikatorem lub typem, który można przekształcić w unikalny identyfikator.

conversation_group_id = conversation_group_id
Określa grupę konwersacji dla otrzymanych wiadomości. Identyfikator grupy rozmów, który jest podawany, musi być unikalnym identyfikatorem lub typem, który można przekonwertować na unikalny identyfikator.

TIMEOUT

Określa czas, w milisekundach, na jaki polecenie czeka na wiadomość. Ta klauzula może być używana tylko z klauzulą WAITFOR. Jeśli ta klauzula nie jest określona lub limit czasu wynosi -1, czas oczekiwania jest nieograniczony. Jeśli czas wygasa RECEIVE , zwraca pusty zestaw wyników.

Remarks

Ważne

Jeśli RECEIVE zdanie nie jest pierwszym zdaniem w procedurze wsadowej lub przechowywanej, poprzedzające zdanie musi być zakończone średnikiem (;).

Instrukcja RECEIVE odczytuje wiadomości z kolejki i zwraca zbiór wyników. Zbiór wyników składa się z zera lub więcej wierszy, z których każdy zawiera jedną wiadomość. Jeśli klauzula INTO nie jest używana, a column_specifier nie przypisuje wartości zmiennym lokalnym, polecenie zwraca zbiór wyników do wywołującego programu.

Wiadomości zwracane przez to polecenie RECEIVE mogą mieć różne typy wiadomości. Aplikacje mogą używać kolumny message_type_name do kierowania każdej wiadomości do kodu obsługującego powiązany typ wiadomości. Istnieją dwie klasy typów wiadomości:

  • Typowe komunikaty zdefiniowane przez aplikację, które zostały utworzone za pomocą CREATE MESSAGE TYPE tego zalecenia. Zestaw typów komunikatów definiowanych przez aplikację, które są dozwolone w rozmowie, jest definiowany przez kontrakt Service Broker określony dla tej rozmowy.

  • Komunikaty systemowe Service Broker zwracają informacje o statusie lub błędzie.

Instrukcja RECEIVE usuwa odebrane wiadomości z kolejki, chyba że kolejka określa zachowanie wiadomości. Gdy ustawienie RETENTION dla kolejki jest WŁĄCZONE, RECEIVE instrukcja aktualizuje kolumnę status do i 0 pozostawia komunikaty w kolejce. Gdy transakcja zawierająca RECEIVE pociąg cofa się, wszystkie zmiany w kolejce w transakcji również są cofane, zwracając wiadomości do kolejki.

Wszystkie wiadomości zwracane przez wywołanie RECEIVE należą do tej samej grupy konwersacyjnej. To RECEIVE zdanie blokuje grupę konwersacji dla wiadomości zwracanych do czasu zakończenia transakcji zawierającej to zdanie. RECEIVE Instrukcja zwraca komunikaty, które mają z status1. Zbiór wyników zwracany przez zdanie RECEIVE jest uporządkowany domyślnie:

  • Jeśli wiadomości z wielu rozmów spełniają warunki klauzuli WHERE, oświadczenie RECEIVE zwraca wszystkie wiadomości z jednej rozmowy, zanim zwróci wiadomości z innej rozmowy. Rozmowy są przetwarzane w kolejności malejącej na poziomie priorytetu.

  • Dla danej rozmowy wywołanie RECEIVE zwraca wiadomości w kolejności rosnącej message_sequence_number .

Klauzula WHERE w RECEIVE zdaniu może zawierać tylko jeden warunek wyszukiwania, który używa albo conversation_handle , albo conversation_group_id. Warunek wyszukiwania nie może zawierać jednej lub więcej innych kolumn w kolejce. Or conversation_handleconversation_group_id nie może być wyrażeniem. Zbiór zwróconych wiadomości zależy od warunków określonych w klauzuli WHERE:

  • Jeśli conversation_handle jest określone, zwraca RECEIVE wszystkie wiadomości z określonej rozmowy dostępne w kolejce.

  • Jeśli conversation_group_id jest określona, RECEIVE zwraca wszystkie wiadomości dostępne w kolejce z dowolnej rozmowy będącej członkiem określonej grupy rozmów.

  • Jeśli nie ma klauzuli WHERE, decyduje, RECEIVE która grupa rozmów:

    • Ma jedną lub więcej wiadomości w kolejce.

    • Nie zostało to zablokowane kolejnym RECEIVE oświadczeniem.

    • Ma najwyższy poziom priorytetu spośród wszystkich grup konwersacyjnych, które spełniają te kryteria.

    RECEIVE następnie zwraca wszystkie wiadomości dostępne w kolejce z dowolnej rozmowy będącej członkiem wybranej grupy rozmowy.

Jeśli uchwyt konwersacji lub identyfikator grupy konwersacji określony w klauzuli WHERE nie istnieje lub nie jest powiązany z określoną kolejką, polecenie zwraca RECEIVE błąd.

Jeśli kolejka określona w RECEIVE instrukcji ma status kolejki ustawiony na WYŁĄCZONE, instrukcja nie udaje się z błędem Transact-SQL.

Gdy określono klauzulę WAITFOR, instrukcja czeka na określony czas lub do momentu dostępności zbioru wyników. Jeśli kolejka zostanie porzucona lub status kolejki jest ustawiony na WYŁĄCZONY podczas oczekiwania polecenia, polecenie natychmiast zwraca błąd. Jeśli oświadczenie RECEIVE określa grupę konwersacji lub kontakt konwersacyjny, a usługa tej rozmowy zostaje usunięta lub przeniesiona do innej kolejki, raportuje RECEIVE błąd Transact-SQL.

RECEIVE nie jest poprawne w funkcji zdefiniowanej przez użytkownika.

Oświadczenie nie RECEIVE ma priorytetu zapobiegania głodzeniu. Jeśli jedno RECEIVE oświadczenie blokuje grupę konwersacji i pobiera wiele wiadomości z rozmów o niskim priorytecie, nie można odebrać żadnych wiadomości z rozmów o wysokim priorytecie w grupie. Aby temu zapobiec, podczas pobierania wiadomości z rozmów o niskim priorytecie użyj klauzuli TOP, aby ograniczyć liczbę wiadomości pobieranych przez każde RECEIVE zdanie.

Kolumny kolejek

Poniższa tabela przedstawia kolumny w kolejce:

Nazwa kolumny Typ danych Opis
status tinyint Stan wiadomości. Dla wiadomości zwróconych przez polecenie RECEIVE status zawsze wynosi .0 Wiadomości w kolejce mogą zawierać jedną z następujących wartości:

0=Gotowi
1=Otrzymana wiadomość
2=Jeszcze nieukończone
3=Zachowana wiadomość wysłana
priority tinyint Poziom priorytetu rozmowy przypisany do wiadomości.
queuing_order bigint Numer kolejki w kolejce.
conversation_group_id uniqueidentifier Identyfikator grupy konwersacyjnej, do której należy ta wiadomość.
conversation_handle uniqueidentifier Omówić rozmowę, której częścią jest ta wiadomość.
message_sequence_number bigint Numer sekwencyjny wiadomości w rozmowie.
service_name nvarchar(128) Nazwa usługi, do której prowadzona jest rozmowa.
service_id int Identyfikator obiektu SQL Server usługi, do której prowadzona jest rozmowa.
service_contract_name nvarchar(128) Nazwa umowy, po której następuje rozmowa.
service_contract_id int Identyfikator obiektu SQL Server kontraktu, po którym następuje rozmowa.
message_type_name nvarchar(128) Nazwa typu wiadomości opisującego format wiadomości. Wiadomości mogą być typami komunikatów aplikacyjnymi lub komunikatami systemu brokera.
message_type_id int Identyfikator obiektu SQL Server o typie wiadomości opisującym tę wiadomość.
validation nchar(2) Walidacja użyta dla wiadomości.

E=Puste
N=Brak
X=XML
message_body varbinary(MAX) Zawartość wiadomości.

Permissions

Aby otrzymać wiadomość, obecny użytkownik musi mieć RECEIVE uprawnienia do kolejki.

Examples

A. Otrzymuj wszystkie kolumny dla wszystkich wiadomości w grupie konwersacyjnej

Poniższy przykład otrzymuje wszystkie dostępne wiadomości dla następnej dostępnej grupy konwersacyjnej z kolejki ExpenseQueue . Instrukcja zwraca wiadomości jako zbiór wyników.

RECEIVE * FROM ExpenseQueue ;  

B. Otrzymuj określone kolumny dla wszystkich wiadomości w grupie konwersacyjnej

Poniższy przykład otrzymuje wszystkie dostępne wiadomości dla następnej dostępnej grupy konwersacyjnej z kolejki ExpenseQueue . Instrukcja zwraca wiadomości jako zbiór wyników zawierający kolumny conversation_handle, message_type_name, oraz message_body.

RECEIVE conversation_handle, message_type_name, message_body  
FROM ExpenseQueue ;  

C. Otrzymaj pierwszą dostępną wiadomość w kolejce

Poniższy przykład otrzymuje pierwszą dostępną wiadomość z kolejki ExpenseQueue jako zestaw wyników.

RECEIVE TOP (1) * FROM ExpenseQueue ;  

D. Otrzymuj wszystkie wiadomości dotyczące określonej rozmowy

Poniższy przykład otrzymuje wszystkie dostępne wiadomości dla określonej rozmowy z kolejki ExpenseQueue jako zestaw wyników.

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

E. Otrzymywanie wiadomości dla określonej grupy konwersacyjnej

Poniższy przykład otrzymuje wszystkie dostępne wiadomości dla określonej grupy konwersacji z kolejki ExpenseQueue jako zestaw wyników.

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. Odbiór do zmiennej tabelowej

Poniższy przykład odbiera wszystkie dostępne wiadomości dla określonej grupy konwersacji z kolejki ExpenseQueue do zmiennej tabelowej.

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. Otrzymuj wiadomości i czekaj w nieskończoność

Poniższy przykład otrzymuje wszystkie dostępne wiadomości dla następnej dostępnej grupy konwersacyjnej w kolejce ExpenseQueue . Instrukcja czeka, aż co najmniej jedna wiadomość stanie się dostępna, a następnie zwraca zestaw wyników zawierający wszystkie kolumny wiadomości.

WAITFOR (  
    RECEIVE *  
    FROM ExpenseQueue) ;  

H. Otrzymuj wiadomości i czeka na określony odstęp czasu

Poniższy przykład otrzymuje wszystkie dostępne wiadomości dla następnej dostępnej grupy konwersacyjnej w kolejce ExpenseQueue . Instrukcja czeka 60 sekund lub do momentu, gdy pojawi się przynajmniej jedna wiadomość, w zależności od tego, co nastąpi wcześniej. Instrukcja zwraca zbiór wyników zawierający wszystkie kolumny wiadomości, jeśli dostępna jest przynajmniej jedna wiadomość. W przeciwnym razie polecenie zwraca pusty zbiór wyników.

WAITFOR (  
    RECEIVE *  
    FROM ExpenseQueue ),  
TIMEOUT 60000 ;  

I. Otrzymuj wiadomości, modyfikując typ kolumny

Poniższy przykład otrzymuje wszystkie dostępne wiadomości dla następnej dostępnej grupy konwersacyjnej w kolejce ExpenseQueue . Gdy typ wiadomości stwierdza, że zawiera dokument XML, polecenie konwertuje treść wiadomości 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. Otrzymanie wiadomości, wyodrębnienie danych z treści wiadomości, pobranie stanu rozmowy

Poniższy przykład otrzymuje następną dostępną wiadomość dla następnej dostępnej grupy konwersacyjnej w kolejce ExpenseQueue . Gdy wiadomość jest typu //Adventure-Works.com/Expenses/SubmitExpense, wyciąga identyfikator pracownika oraz listę elementów z treści wiadomości. Oświadczenie również przywołuje stan rozmowy ze stołu 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 ;