RECEIVE (Transact-SQL)
Recupera uno o más mensajes de una cola. En función del valor de retención de la cola, se elimina el mensaje de la cola o se actualiza el estado del mensaje de la cola.
Sintaxis
[ 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
}
Argumentos
- WAITFOR
Especifica que la instrucción RECEIVE espera a que llegue un mensaje a la cola en caso de no haber ningún mensaje.
- TOP( n )
Especifica el número máximo de mensajes que se van a devolver. Si no se especifica esta cláusula, se devuelven todos los mensajes que cumplen los criterios de la instrucción.
- *
Especifica que el conjunto de resultados contiene todas las columnas de la cola.
- column_name
Es el nombre de la columna que se va a incluir en el conjunto de resultados.
- expression
Es un nombre de columna, constante, función o una combinación de nombres de columnas, constantes y funciones conectados mediante operadores.
- column_alias
Es un nombre alternativo para reemplazar el nombre de la columna en el conjunto de resultados.
- FROM
Especifica la cola que contiene los mensajes que se van a recuperar.
- database_name
Es el nombre de la base de datos que contiene la cola desde la que se van a recibir los mensajes. Si no se proporciona database_name, el valor predeterminado es la base de datos actual.
- schema_name
Es el nombre del esquema al que pertenece la cola desde la que se van a recibir los mensajes. Si no se proporciona schema_name, se utiliza el esquema predeterminado del usuario actual.
- queue_name
Es el nombre de la cola desde la que se reciben los mensajes.
- INTO table_variable
Especifica la tabla que se va a seleccionar en las columnas de los mensajes recibidos.
- WHERE
Especifica la conversación o grupo de conversación para los mensajes recibidos. Si se omite, se devuelven los mensajes del siguiente grupo de conversación disponible.
- conversation_handle = conversation_handle
Especifica la conversación para los mensajes recibidos. El valor de conversation_handle proporcionado debe ser un uniqueidentifer o un tipo convertible en uniqueidentifier.
- conversation_group_id = conversation_group_id
Especifica el grupo de conversación para los mensajes recibidos. El valor de conversation_group_id proporcionado debe ser un uniqueidentifier o un tipo convertible en uniqueidentifier.
- TIMEOUT timeout
Especifica el tiempo, en milisegundos, durante el que la instrucción espera un mensaje. Esta cláusula sólo se puede utilizar con la cláusula WAITFOR. Si no se especifica esta cláusula o el tiempo de espera es -1, el tiempo de espera es ilimitado. Si se agota el tiempo de espera, RECEIVE devuelve un conjunto de resultados vacío.
Notas
Importante: |
---|
Si la instrucción RECEIVE no es la primera de un lote o un procedimiento almacenado, la instrucción anterior debe terminar en un punto y coma (;), que es el terminador de instrucciones Transact-SQL. |
La instrucción RECEIVE lee los mensajes de una cola y devuelve un conjunto de resultados. El conjunto de resultados devuelto consta de cero o más filas, cada una de las cuales contiene un mensaje. Si no se utiliza la cláusula INTO y column_specifier no asigna valores a las variables locales, la instrucción devuelve un conjunto de resultados al programa que realiza la llamada.
La instrucción RECEIVE quita los mensajes recibidos de la cola a menos que la cola especifique la retención de mensajes. Si el valor RETENTION para la cola está activado, la instrucción RECEIVE actualiza la columna status a 1 y deja los mensajes en la cola. Si se revierte una transacción que contiene la instrucción RECEIVE, también se revierten todos los cambios de la cola de la transacción y se devuelven los mensajes a la cola.
Todos los mensajes devueltos por una instrucción RECEIVE pertenecen al mismo grupo de conversación. La instrucción RECEIVE bloquea el grupo de conversación para los mensajes devueltos hasta que se completa la transacción que contiene la instrucción. El conjunto de resultados devuelto por la instrucción RECEIVE se ordena de forma implícita. Para una conversación determinada, la instrucción RECEIVE devuelve mensajes con un status de 1 con un orden de message_sequence_number ascendente.
La cláusula WHERE de la instrucción RECEIVE sólo puede contener condiciones de búsqueda que utilizan conversation_handle o conversation_group_id. La condición de búsqueda puede no contener alguna del resto de las columnas de la cola. conversation_handle o conversation_group_id pueden no ser una expresión. Si no se especifica una cláusula WHERE, la instrucción RECEIVE devuelve mensajes del siguiente grupo de conversación disponible con independencia de los bloqueos que la conexión actual mantiene en otros grupos de conversación. Si la cláusula WHERE no especifica un conversation_handle, la instrucción RECEIVE devuelve mensajes del grupo de conversación con independencia de la conversación a la que pertenece cada mensaje. Si el identificador de conversación o el identificador del grupo de conversación especificado en la cláusula WHERE no existe o no está asociado a la cola especificada, la instrucción RECEIVE devuelve un error.
Si la cola especificada en la instrucción RECEIVE tiene el estado de cola establecido en OFF, la instrucción genera un error de Transact-SQL.
Si se especifica la cláusula WAITFOR, la instrucción espera a que se agote el tiempo de espera especificado o hasta que haya un conjunto de resultados disponible. Si se quita la cola o su estado se establece en OFF mientras la instrucción está esperando, dicha instrucción devuelve un error de inmediato. Si la instrucción RECEIVE especifica un grupo de conversación o un identificador de conversación y se quita o se mueve el servicio para dicha conversación a otra cola, la instrucción RECEIVE informa de un error de Transact-SQL.
RECEIVE no tiene validez en una función definida por el usuario.
La siguiente tabla contiene las columnas de una cola.
Nombre de columna | Tipo de datos | Descripción |
---|---|---|
status |
tinyint |
Estado del mensaje. Para los mensajes devueltos por el comando RECEIVE, el estado es siempre 0. Los mensajes de la cola pueden contener uno de los siguientes valores: 0=Listo1=Mensaje recibido2=Sin completar3=Mensaje enviado retenido |
priority |
tinyint |
0. Identificado para fines informativos solamente. No compatible. La compatibilidad con versiones posteriores no está garantizada.. |
queuing_order |
bigint |
Número de orden de los mensajes en la cola. |
conversation_group_id |
uniqueidentifier |
Identificador para el grupo de conversación al que pertenece este mensaje. |
conversation_handle |
uniqueidentifier |
Identificador para la conversación de la que forma parte este mensaje. |
message_sequence_number |
bigint |
Número de secuencia del mensaje en la conversación. |
service_name |
nvarchar(512) |
Nombre del servicio al que se destina la conversación. |
service_id |
int |
Identificador de objeto de SQL Server del servicio al que se destina la conversación. |
service_contract_name |
nvarchar(256) |
Nombre del contrato por el que se rige la conversación. |
service_contract_id |
int |
Identificador de objeto de SQL Server del contrato por el que se rige la conversación. |
message_type_name |
nvarchar(256) |
Nombre del tipo de mensaje que describe el mensaje. |
message_type_id |
int |
Identificador de objeto de SQL Server del tipo de mensaje que describe el mensaje. |
validation |
nchar(2) |
Validación utilizada para el mensaje. E=VacíaN=NingunaX=XML |
message_body |
varbinary(MAX) |
Contenido del mensaje. |
Permisos
Para recibir un mensaje, el usuario actual debe tener el permiso RECEIVE en la cola.
Ejemplos
A. Recibir todas las columnas para todos los mensajes en un grupo de conversación
En el siguiente ejemplo se reciben todos los mensajes disponibles para el próximo grupo de conversación disponible desde la cola ExpenseQueue
. La instrucción devuelve los mensajes como un conjunto de resultados.
RECEIVE * FROM ExpenseQueue ;
B. Recibir las columnas especificadas para todos los mensajes en un grupo de conversación
En el siguiente ejemplo se reciben todos los mensajes disponibles para el próximo grupo de conversación disponible desde la cola ExpenseQueue
. La instrucción devuelve los mensajes como un conjunto de resultados que contiene las columnas conversation_handle
, message_type_name
y message_body
.
RECEIVE conversation_handle, message_type_name, message_body
FROM ExpenseQueue ;
C. Recibir el primer mensaje disponible en la cola
En el siguiente ejemplo se recibe el primer mensaje disponible en la cola ExpenseQueue
como un conjunto de resultados.
RECEIVE TOP (1) * FROM ExpenseQueue ;
D. Recibir todos los mensajes para una conversación especificada
En el siguiente ejemplo se reciben todos los mensajes disponibles para la conversación especificada desde la cola ExpenseQueue
como un conjunto de resultados.
DECLARE @conversation_handle UNIQUEIDENTIFIER ;
SET @conversation_handle = <retrieve conversation from database> ;
RECEIVE *
FROM ExpenseQueue
WHERE conversation_handle = @conversation_handle ;
E. Recibir mensajes para un grupo de conversación especificado
En el siguiente ejemplo se reciben todos los mensajes disponibles para el grupo de conversación especificado desde la cola ExpenseQueue
como un conjunto de resultados.
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. Recibir en una variable de tabla
En el siguiente ejemplo se reciben todos los mensajes disponibles para el grupo de conversación especificado desde la cola ExpenseQueue
en una variable de tabla.
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. Recibir mensajes y esperar indefinidamente
En el siguiente ejemplo se reciben todos los mensajes disponibles para el próximo grupo de conversación disponible en la cola ExpenseQueue
. La instrucción espera hasta que un mensaje como mínimo se encuentra disponible como un conjunto de resultados que contiene todas las columnas de mensajes.
WAITFOR (
RECEIVE *
FROM ExpenseQueue) ;
H. Recibir mensajes y esperar durante un intervalo especificado
En el siguiente ejemplo se reciben todos los mensajes disponibles para el próximo grupo de conversación disponible en la cola ExpenseQueue
. La instrucción espera 60 segundos o hasta que hay disponible un mensaje como mínimo (lo que suceda en primer lugar). La instrucción devuelve un conjunto de resultados que contiene todas las columnas de mensajes si hay disponible un mensaje como mínimo, y en caso contrario la instrucción devuelve un conjunto de resultados vacío.
WAITFOR (
RECEIVE *
FROM ExpenseQueue ),
TIMEOUT 60000 ;
I. Recibir mensajes y modificar el tipo de columna
En el siguiente ejemplo se reciben todos los mensajes disponibles para el próximo grupo de conversación disponible en la cola ExpenseQueue
. Si el tipo de mensaje indica que el mensaje contiene un documento XML, la instrucción convierte el cuerpo del mensaje a 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. Recibir un mensaje, extraer los datos del cuerpo del mensaje y recuperar el estado de la conversación
En el siguiente ejemplo se recibe el siguiente mensaje disponible para el próximo grupo de conversación disponible en la cola ExpenseQueue
. Si el mensaje es de tipo //Adventure-Works.com/Expenses/SubmitExpense
, la instrucción extrae el Id. de empleado y una lista de los elementos del cuerpo del mensaje. La instrucción recupera además el estado de la conversación de la tabla 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 = "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 ;
Vea también
Referencia
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)
Otros recursos
Tutoriales de Service Broker
Conversation Group Locks
Arquitectura de la conversación