RECEIVE (Transact-SQL)
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.
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 ]
| column_alias = expression
} [ ,...n ]
<queue> ::=
{
[ database_name . [ schema_name ] . | schema_name . ]
queue_name
}
Argumente
- WAITFOR
Gibt an, dass die RECEIVE-Anweisung darauf wartet, dass eine Nachricht für die Warteschlange eintrifft, wenn 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.
- *
Gibt an, dass das Resultset alle Spalten in der Warteschlange umfasst.
- column_name
Der Name einer Spalte, die in das Resultset mit 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. Wird database_name nicht angegeben, wird standardmäßig die aktuelle Datenbank verwendet.
- schema_name
Der Name des Schemas, das Besitzer der Warteschlange ist, von der Nachrichten empfangen werden. Wird schema_name nicht angegeben, wird standardmäßig das Standardschema für den aktuellen Benutzer verwendet.
- queue_name
Der Name der Warteschlange, von der Nachrichten empfangen werden.
- INTO table_variable
Gibt die Tabelle an, die für die Spalten der empfangenen Nachrichten ausgewählt werden soll.
- 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. Bei dem für conversation_handle angegebenen Wert muss es sich um den Datentyp uniqueidentifer handeln oder um einen Typ, der in uniqueidentifier konvertiert werden kann.
- conversation_group_id = conversation_group_id
Gibt die Konversationsgruppe für die empfangenen Nachrichten an. Bei dem für conversation_group_id angegebenen Wert muss es sich um den Datentyp uniqueidentifier handeln oder um einen Typ, der in uniqueidentifier konvertiert werden kann.
- TIMEOUT timeout
Gibt in Millisekunden an, wie lange die Anweisung auf eine Nachricht warten soll. Diese Klausel darf nur zusammen mit der WAITFOR-Klausel verwendet werden. Wird die Klausel nicht angegeben oder hat das Timeout den Wert -1, dann ist die Wartezeit unbegrenzt. Läuft das Timeout ab, gibt RECEIVE ein leeres Resultset zurück.
Hinweise
Wichtig: |
---|
Wenn es sich bei der RECEIVE-Anweisung nicht um die erste Anweisung in einem Batch oder in einer gespeicherten Prozedur handelt, muss die vorhergehende Anweisung mit einem Semikolon (;) abgeschlossen werden, also mit dem Abschlusszeichen für eine Transact-SQL-Anweisung. |
Die RECEIVE-Anweisung liest Nachrichten aus einer Warteschlange und gibt ein Resultset 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.
Mit der RECEIVE-Anweisung werden erhaltene Nachrichten aus der Warteschlange entfernt, es sei denn, für die Warteschlange ist die Aufbewahrung von Nachrichten festgelegt. Ist als Einstellung für RETENTION für die Warteschlange der Wert ON festgelegt, dann aktualisiert die RECEIVE-Anweisung den Wert in der Spalte status auf 1 und belässt die Nachricht in der Warteschlange. Wenn ein Rollback für eine Transaktion erfolgt, die eine RECEIVE-Anweisung enthält, erfolgt auch ein Rollback für alle Änderungen in der Warteschlange innerhalb der Transaktion, und die Nachrichten werden der Warteschlange zurückgegeben.
Alle Nachrichten, die von einer RECEIVE-Anweisung zurückgegeben werden, gehören derselben Konversationsgruppe an. Die RECEIVE-Anweisung sperrt die Konversationsgruppe für die zurückgegebenen Nachrichten so lange, bis die Transaktion, die die Anweisung enthält, abgeschlossen ist. Das Resultset, das von einer RECEIVE-Anweisung zurückgegeben wird, ist implizit angeordnet. Für eine bestimmte Konversation gibt eine RECEIVE-Anweisung Nachrichten, bei denen status den Wert 1 hat, fürmessage_sequence_number in aufsteigender Reihenfolge zurück.
Die WHERE-Klausel der RECEIVE-Anweisung darf nur Suchbedingungen enthalten, die conversation_handle oder conversation_group_id verwenden. Die Suchbedingung darf keine der anderen Spalten in der Warteschlange umfassen. Ein Ausdruck darf nicht conversation_handle oder conversation_group_id enthalten. Wird keine WHERE-Klausel angegeben, gibt die RECEIVE-Anweisung Nachrichten aus der nächsten verfügbaren Konversationsgruppe zurück, unabhängig von Sperren, die die aktuelle Verbindung möglicherweise auf andere Konversationsgruppen anwendet. Gibt die WHERE-Klausel keinen Wert für conversation_handle an, gibt die RECEIVE-Anweisung Nachrichten aus der Konversationsgruppe zurück, und zwar unabhängig von der Konversation, zu der die jeweilige Nachricht gehört. Ist das in der WHERE-Klausel angegebene Konversationshandle oder der für die Konversationsgruppe angegebene Bezeichner nicht vorhanden oder nicht mit der angegebenen Warteschlange verknüpft, dann gibt die RECEIVE-Anweisung einen Fehler zurück.
Ist als Status für die in der RECEIVE-Anweisung angegebene Warteschlange der Wert OFF festgelegt, schlägt die Anweisung mit einem Transact-SQL-Fehler fehl.
Wird die WAITFOR-Klausel angegeben, wartet die Anweisung bis zum Ablauf des angegebenen Timeouts oder so lange, 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 ein Konversationshandle angibt und wenn der Dienst für diese Konversation gelöscht oder zu einer anderen Warteschlange verschoben wird, dann gibt die RECEIVE-Anweisung einen Transact-SQL-Fehler zurück.
RECEIVE ist in einer benutzerdefinierten Funktion nicht gültig.
In der folgenden Tabelle werden die Spalten in einer Warteschlange aufgelistet.
Spaltenname | Datentyp | Beschreibung |
---|---|---|
status |
tinyint |
Status der Nachricht. Für Nachrichten, die vom RECEIVE-Befehl zurückgegeben werden, ist der Status immer 0. Nachrichten in der Warteschlange können einen der folgenden Werte enthalten: 0=Bereit1=Nachricht empfangen2=Noch nicht abgeschlossen3=Gesendete Nachricht wurde beibehalten |
priority |
tinyint |
0. Nur für Informationszwecke identifiziert. Nicht unterstützt. Zukünftige Kompatibilität wird nicht sichergestellt.. |
queuing_order |
bigint |
Fortlaufende Nummer der Nachricht innerhalb 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 innerhalb der Konversation |
service_name |
nvarchar(512) |
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(256) |
Name des Vertrags, dem die Konversation entspricht |
service_contract_id |
int |
SQL Server-Objektbezeichner des Vertrags, dem die Konversation entspricht |
message_type_name |
nvarchar(256) |
Name des Nachrichtentyps, der die Nachricht beschreibt |
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 erhalten zu können, muss der aktuelle Benutzer über eine RECEIVE-Berechtigung für die Warteschlange verfügen.
Beispiele
A. Empfangen aller Spalten für alle Nachrichten in einer Konversationsgruppe
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 bestimmter Spalten für alle Nachrichten in einer Konversationsgruppe
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 angegebene Konversation
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 Konversationsgruppe
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 einer Tabellenvariablen
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 bei unbegrenzter Wartezeit
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 umfasst, 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 Spaltentyps
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 und Abrufen des Konversationsstatus
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 = "http://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 = "http://Adventure-Works.com/schemas/expenseReport"
/rpt:ExpenseReport/rpt:ItemDetail')
ELSE NULL
END AS ItemList
FROM ExpenseQueue
), TIMEOUT 60000 ;
Siehe auch
Verweis
BEGIN DIALOG CONVERSATION (Transact-SQL)
BEGIN CONVERSATION TIMER (Transact-SQL)
END CONVERSATION (Transact-SQL)
SEND (Transact-SQL)
CREATE QUEUE (Transact-SQL)
ALTER QUEUE (Transact-SQL)
DROP QUEUE (Transact-SQL)
Andere Ressourcen
Service Broker-Lernprogramme
Conversation Group Locks
Konversationsarchitektur