Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Gilt für:SQL Server
Azure SQL Managed Instance
Ruft eine oder mehrere Nachrichten aus einer Warteschlange ab. Je nach den Einstellungen für die Warteschlange wird entweder die Nachricht aus der Warteschlange entfernt oder der Status der Nachricht in der Warteschlange aktualisiert.
Transact-SQL-Syntaxkonventionen
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 }
Argumente
WAITFOR
Gibt an, dass die RECEIVE Anweisung darauf wartet, dass eine Nachricht in der Warteschlange eintrifft, falls derzeit keine Nachrichten vorhanden sind.
TOP( n )
Gibt die maximale Anzahl von Nachrichten an, die zurückgegeben werden. Wird diese Klausel nicht angegeben, werden alle Nachrichten zurückgegeben, die die Kriterien der Anweisung erfüllen.
column_specifier
*
Gibt an, dass das Resultset alle Spalten in der Warteschlange umfasst.
column_name
Der Name einer Spalte, die in das Resultset aufgenommen werden soll.
expression
Ein Spaltenname, eine Konstante, eine Funktion oder eine beliebige, durch Operatoren verknüpfte Kombination von Spaltennamen, Konstanten und Funktionen.
column_alias
Ein alternativer Name, der den Spaltennamen im Resultset ersetzt.
FROM
Gibt die Warteschlange an, die die Nachrichten enthält, die abgerufen werden sollen.
database_name
Der Name der Datenbank, die die Warteschlange enthält, von der Nachrichten empfangen werden. Wenn database_name nicht bereitgestellt wird, wird standardmäßig die aktuelle Datenbank verwendet.
schema_name
Der Name des Schemas, das Besitzer der Warteschlange ist, von der Nachrichten empfangen werden. Wenn schema_name nicht angegeben wird, wird standardmäßig das Standardschema für den aktuellen Benutzer verwendet.
queue_name
Der Name der Warteschlange, von der Nachrichten empfangen werden.
IN table_variable
Spezifiziert die Tabellenvariable, in die RECEIVE die Nachrichten eingelegt werden. Die Tabellenvariable muss die gleiche Anzahl von Spalten wie die Nachrichten enthalten. Die Datentypen der einzelnen Spalten in der Tabellenvariablen müssen implizit in den Datentyp der entsprechenden Spalte in den Nachrichten konvertiert werden können. Wenn INTO nicht angegeben wird, werden die Nachrichten als Resultset zurückgegeben.
WHERE
Gibt die Konversation oder Konversationsgruppe für die empfangenen Nachrichten an. Wird kein Wert angegeben, werden Nachrichten aus der nächsten verfügbaren Konversationsgruppe zurückgegeben.
conversation_handle = conversation_handle
Gibt die Konversation für die empfangenen Nachrichten an. Das bereitgestellte Unterhaltungshandle muss ein eindeutiger Bezeichner oder ein Typ sein, der in einen eindeutigen Eindeutiger wandelbar ist.
conversation_group_id = conversation_group_id
Gibt die Konversationsgruppe für die empfangenen Nachrichten an. Der bereitgestellte Konversationsgruppen-ID muss dem Typ uniqueidentifer oder einem Typ entsprechen, der in uniqueidentifer konvertierbar ist.
TIMEOUT-Auszeit
Gibt in Millisekunden an, wie lange die Anweisung auf eine Nachricht warten soll. Diese Klausel kann nur zusammen mit der WAITFOR-Klausel verwendet werden. Wenn diese Klausel nicht angegeben ist oder das Timeout erfolgt -1, ist die Wartezeit unbegrenzt. Wenn das Timeout abläuft, RECEIVE wird eine leere Ergebnismenge zurückgegeben.
Hinweise
Wichtig
Wenn die RECEIVE Anweisung nicht die erste Anweisung in einem Batch oder gespeicherten Verfahren ist, muss die vorherige Aussage mit einem Semikolon (;)) endet.
Die RECEIVE Anweisung liest Nachrichten aus einer Warteschlange und gibt ein Ergebnisset zurück. Das zurückgegebene Resultset besteht aus null oder mehr Zeilen, wobei jede Zeile eine Nachricht umfasst. Wenn die INTO-Klausel nicht verwendet wird und column_specifier die Werte nicht lokalen Variablen zuordnet, dann gibt die Anweisung ein Resultset an das aufrufende Programm zurück.
Die von der Anweisung RECEIVE zurückgegebenen Nachrichten können verschiedene Nachrichtentypen haben. In Anwendungen kann die Spalte message_type_name verwendet werden, um jede Nachricht an Code weiterzuleiten, der den zugehörigen Nachrichtentyp behandelt. Die folgenden zwei Klassen von Nachrichtentypen stehen zur Verfügung:
Anwendungsdefinierte Nachrichtentypen, die durch die Verwendung der Anweisung CREATE MESSAGE TYPE erstellt wurden. Der in einer Konversation zulässige Satz von anwendungsdefinierten Nachrichtentypen wird durch den für die Konversation angegebenen Service Broker-Vertrag definiert.
Service Broker-Systemmeldungen, die Status- oder Fehlerinformationen zurückgeben.
Die Anweisung RECEIVE entfernt empfangene Nachrichten aus der Warteschlange, es sei denn, die Warteschlange gibt die Nachrichtenaufbewahrung an. Wenn die RETENTION-Einstellung für die Warteschlange ON ist, aktualisiert die Anweisung RECEIVE die status Spalte auf 0 und verlässt die Nachrichten in der Warteschlange. Wenn eine Transaktion, die eine RECEIVE Anweisung enthält, zurückrollt, werden auch alle Änderungen an der Warteschlange in der Transaktion zurückgesetzt, wodurch Nachrichten an die Warteschlange zurückgegeben werden.
Alle Nachrichten, die durch eine RECEIVE Aussage zurückgegeben werden, gehören zur gleichen Gesprächsgruppe. Die Anweisung RECEIVE sperrt die Konversationsgruppe für die zurückgegebenen Nachrichten, bis die Transaktion mit der Anweisung abgeschlossen ist. Eine Anweisung liefert RECEIVE Nachrichten zurück, die ein status von haben 1. Die von einer RECEIVE Aussage zurückgegebene Ergebnismenge ist implizit geordnet:
Wenn Nachrichten aus mehreren Konversationen die WHERE-Klauselbedingungen erfüllen, gibt die RECEIVE Anweisung alle Nachrichten aus einer Konversation zurück, bevor sie Nachrichten für andere Konversationen zurückgibt. Die Konversationen werden in der Reihenfolge absteigender Priorität verarbeitet.
Für ein bestimmtes Gespräch gibt eine RECEIVE Aussage Nachrichten in aufsteigender Reihenfolge
message_sequence_numberzurück.
Die WHERE-Klausel der RECEIVE Anweisung kann nur eine Suchbedingung enthalten, die entweder conversation_handle oder conversation_group_idverwendet. Die Suchbedingung kann keine der anderen Spalten in der Warteschlange umfassen.
conversation_handle oder conversation_group_id darf kein Ausdruck sein. Welcher Satz an Nachrichten zurückgegeben wird, hängt von den Bedingungen ab, die in der WHERE-Klausel angegeben sind:
Wenn conversation_handle angegeben ist, RECEIVE gibt es alle Nachrichten aus der angegebenen Konversation zurück, die in der Warteschlange verfügbar sind.
Wenn conversation_group_id angegeben ist, RECEIVE gibt es alle Nachrichten zurück, die in der Warteschlange von einer Konstrukte, die Mitglied der angegebenen Gesprächsgruppe sind.
Wenn es keine WHERE-Klausel gibt, bestimmt sie, RECEIVE welche Gesprächsgruppe:
Es sind eine oder mehrere Nachrichten in der Warteschlange verfügbar.
Wurde nicht durch eine andere RECEIVE Aussage gesperrt.
Weist von allen Konversationsgruppen, die diese Kriterien erfüllen, die höchste Prioritätsebene auf.
RECEIVE dann gibt alle in der Warteschlange verfügbaren Nachrichten aus einer Konseignation zurück, die Mitglied der ausgewählten Gesprächsgruppe ist.
Wenn der in der WHERE-Klausel angegebene Konversationshandle- oder Konversationsgruppen-Identifikator nicht existiert oder nicht mit der angegebenen Warteschlange verknüpft ist, gibt die RECEIVE Anweisung einen Fehler zurück.
Wenn die in der RECEIVE Anweisung angegebene Warteschlange den Warteschlangenstatus auf OFF gesetzt hat, schlägt die Anweisung mit einem Transact-SQL-Fehler fehl.
Wird die WAITFOR-Klausel angegeben, wird mit der Ausführung der Anweisung bis zum Ablauf des angegebenen Timeouts oder so lange gewartet, bis ein Resultset verfügbar ist. Wird die Warteschlange gelöscht, oder wird als Status für die Warteschlange OFF angegeben, während eine Anweisung wartet, gibt die Anweisung sofort einen Fehler zurück. Wenn die RECEIVE Anweisung eine Konversationsgruppe oder einen Konversationshandle angibt und der Dienst für diese Konversation verworfen oder in eine andere Warteschlange verschoben wird, meldet die RECEIVE Anweisung einen Transact-SQL-Fehler.
RECEIVE ist in einer benutzerdefinierten Funktion nicht gültig.
Die Aussage RECEIVE hat keine vorrangige Verhütung von Hunger. Wenn eine einzelne RECEIVE Aussage eine Gesprächsgruppe sperrt und viele Nachrichten aus niedrig priorisierten Konversationen abruft, können keine Nachrichten von hochpriorisierten Unterhaltungen in der Gruppe empfangen werden. Um dies zu verhindern, verwenden Sie beim Abrufen von Nachrichten aus Konversationen mit niedriger Priorität die TOP-Klausel, um die Anzahl der von jeder RECEIVE Anweisung abgerufenen Nachrichten zu begrenzen.
Spalten in der Warteschlange
In der folgenden Tabelle werden die Spalten einer Warteschlange aufgelistet.
| Spaltenname | Datentyp | Beschreibung |
|---|---|---|
status |
tinyint | Status der Nachricht. Für vom Befehl RECEIVE zurückgegebene Nachrichten ist der Status immer 0. Nachrichten in der Warteschlange können einen der folgenden Werte enthalten:0=Bereit1=Empfangene Nachricht2=Noch nicht abgeschlossen3=Gesendete Nachricht beibehalten |
priority |
tinyint | Die Prioritätsebene der Konversation, die auf die Nachricht angewendet wird. |
queuing_order |
bigint | Fortlaufende Nummer der Nachricht in der Warteschlange. |
conversation_group_id |
uniqueidentifier | Bezeichner für die Konversationsgruppe, zu der diese Nachricht gehört. |
conversation_handle |
uniqueidentifier | Handle der Konversation, von der diese Nachricht ein Teil ist. |
message_sequence_number |
bigint | Sequenznummer der Nachricht in der Konversation. |
service_name |
nvarchar(128) | Name des Diensts, an den die Konversation gerichtet ist. |
service_id |
int | SQL Server-Objektbezeichner des Diensts, an den die Konversation gerichtet ist. |
service_contract_name |
nvarchar(128) | Name des Vertrags, dem die Konversation entspricht. |
service_contract_id |
int | SQL Server-Objektbezeichner des Vertrags, dem die Konversation entspricht. |
message_type_name |
nvarchar(128) | Name des Nachrichtentyps, der das Format der Nachricht beschreibt. Nachrichten können entweder vom Typ Anwendungsnachricht oder Brokersystemmeldungen sein. |
message_type_id |
int | SQL Server-Objektbezeichner des Nachrichtentyps, der die Nachricht beschreibt. |
validation |
nchar(2) | Für die Nachricht verwendete Überprüfung.E=LeerN=KeineX=XML |
message_body |
varbinary(MAX) | Inhalt der Nachricht. |
Berechtigungen
Um eine Nachricht zu empfangen, muss der aktuelle Benutzer eine Berechtigung für die Warteschlange haben RECEIVE .
Beispiele
A. Empfangen aller Spalten für alle Nachrichten in einer Unterhaltungsgruppe
Im folgenden Beispiel werden alle verfügbaren Nachrichten für die nächste verfügbare Konversationsgruppe aus der ExpenseQueue-Warteschlange empfangen. Die Anweisung gibt die Nachrichten als Resultset zurück.
RECEIVE * FROM ExpenseQueue ;
B. Empfangen von angegebenen Spalten für alle Nachrichten in einer Unterhaltungsgruppe
Im folgenden Beispiel werden alle verfügbaren Nachrichten für die nächste verfügbare Konversationsgruppe aus der ExpenseQueue-Warteschlange empfangen. Die Anweisung gibt die Nachrichten als Resultset zurück, das die Spalten conversation_handle, message_type_name und message_body umfasst.
RECEIVE conversation_handle, message_type_name, message_body
FROM ExpenseQueue ;
C. Empfangen der ersten verfügbaren Nachricht in der Warteschlange
Im folgenden Beispiel wird die erste verfügbare Nachricht aus der ExpenseQueue-Warteschlange als Resultset empfangen.
RECEIVE TOP (1) * FROM ExpenseQueue ;
D: Empfangen aller Nachrichten für eine bestimmte Unterhaltung
Im folgenden Beispiel werden alle verfügbaren Nachrichten für die angegebene Konversation aus der ExpenseQueue-Warteschlange als Resultset empfangen.
DECLARE @conversation_handle UNIQUEIDENTIFIER ;
SET @conversation_handle = <retrieve conversation from database> ;
RECEIVE *
FROM ExpenseQueue
WHERE conversation_handle = @conversation_handle ;
E. Empfangen von Nachrichten für eine angegebene Unterhaltungsgruppe
Im folgenden Beispiel werden alle verfügbaren Nachrichten für die angegebene Konversationsgruppe aus der ExpenseQueue-Warteschlange als Resultset empfangen.
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. Empfangen in eine Tabellenvariable
Im folgenden Beispiel werden alle verfügbaren Nachrichten für eine angegebene Konversationsgruppe aus der ExpenseQueue-Warteschlange in einer Tabellenvariablen empfangen.
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. Empfangen von Nachrichten und Warten auf unbestimmte Zeit
Im folgenden Beispiel werden alle verfügbaren Nachrichten für die nächste verfügbare Konversationsgruppe in der ExpenseQueue-Warteschlange empfangen. Die Anweisung wartet, bis mindestens eine Nachricht verfügbar ist. Sie gibt dann ein Resultset zurück, das alle Nachrichtenspalten enthält.
WAITFOR (
RECEIVE *
FROM ExpenseQueue) ;
H. Empfangen von Nachrichten und Warten auf ein angegebenes Intervall
Im folgenden Beispiel werden alle verfügbaren Nachrichten für die nächste verfügbare Konversationsgruppe in der ExpenseQueue-Warteschlange empfangen. Die Anweisung wartet 60 Sekunden oder so lange, bis mindestens eine Nachricht verfügbar ist, je nachdem, welches Ereignis zuerst eintritt. Die Anweisung gibt ein Resultset zurück, das alle Nachrichtenspalten enthält, wenn mindestens eine Nachricht verfügbar ist. Andernfalls gibt die Anweisung ein leeres Resultset zurück.
WAITFOR (
RECEIVE *
FROM ExpenseQueue ),
TIMEOUT 60000 ;
I. Empfangen von Nachrichten, Ändern des Typs einer Spalte
Im folgenden Beispiel werden alle verfügbaren Nachrichten für die nächste verfügbare Konversationsgruppe in der ExpenseQueue-Warteschlange empfangen. Wenn über den Nachrichtentyp angegeben wird, dass die Nachricht ein XML-Dokument enthält, dann konvertiert die Anweisung den Nachrichtentext in 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. Empfangen einer Nachricht, Extrahieren von Daten aus dem Nachrichtentext, Abrufen des Unterhaltungszustands
Im folgenden Beispiel wird die nächste verfügbare Nachricht für die nächste verfügbare Konversationsgruppe in der ExpenseQueue-Warteschlange empfangen. Im Falle des Nachrichtentyps //Adventure-Works.com/Expenses/SubmitExpense extrahiert die Anweisung die Employee ID und eine Liste von Elementen aus dem Nachrichtentext. Die Anweisung ruft auch den Status der Konversation aus der ConversationState-Tabelle ab.
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 ;