RECEIVE (Transact-SQL)

Récupère un ou plusieurs messages dans une file d'attente. Selon le paramètre de rétention défini pour la file d'attente, supprime le message de la file d'attente ou met à jour l'état du message dans la file d'attente.

Syntaxe

[ 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
}

Arguments

  • WAITFOR
    Indique que l'instruction RECEIVE attend qu'un message arrive dans la file d'attente, si aucun message n'est actuellement présent.
  • TOP( n )
    Indique le nombre maximal de messages à retourner. Si cette clause n'est pas spécifiée, tous les messages qui satisfont aux critères de l'instruction sont retournés.
  • *
    Indique que le jeu de résultats contient toutes les colonnes de la file d'attente.
  • column_name
    Nom de la colonne à inclure dans le jeu de résultats.
  • expression
    Nom de colonne, constante, fonction ou toute combinaison de noms de colonnes, de constantes ou de fonctions reliés par un opérateur.
  • column_alias
    Nom utilisé pour remplacer le nom de colonne dans le jeu de résultats.
  • FROM
    Indique la file d'attente contenant les messages à récupérer.
  • database_name
    Nom de la base de données contenant la file d'attente à partir de laquelle les messages sont envoyés. Lorsqu'aucun argument database_name n'est fourni, la base de données active est utilisée par défaut.
  • schema_name
    Nom du schéma propriétaire de la file d'attente à partir de laquelle les messages sont envoyés. Lorsqu'aucun argument schema_name n'est fourni, le schéma actif par défaut pour l'utilisateur actuel est utilisé par défaut.
  • queue_name
    Nom de la file d'attente à partir de laquelle les messages sont envoyés.
  • INTO table_variable
    Indique la table pour sélectionner les colonnes des messages reçus.
  • WHERE
    Indique la conversation ou le groupe de conversations des messages reçus. Si cette clause est omise, retourne les messages du groupe de conversations suivant disponible.
  • conversation_handle = conversation_handle
    Indique la conversation pour les messages reçus. L'argument conversation_handle fourni doit être de type uniqueidentifer ou convertible en type uniqueidentifier.
  • conversation_group_id = conversation_group_id
    Indique la conversation pour les messages reçus. L'argument conversation_group_id fourni doit être de type uniqueidentifier ou convertible en type uniqueidentifier.
  • TIMEOUT timeout
    Indique le temps, en millisecondes, pendant lequel l'instruction attend un message. Cette clause ne peut être utilisée qu'avec la clause WAITFOR. Si cette clause est omise ou si le délai d'attente a la valeur -1, le délai d'attente est illimitée. Si le délai d'attente expire, l'instruction RECEIVE retourne un jeu de résultats vide.

Notes

ms186963.note(fr-fr,SQL.90).gifImportant :
Si l'instruction RECEIVE n'est pas la première instruction d'un lot ou d'une procédure stockée, l'instruction précédente doit se terminer par un point-virgule (;), le terminateur d'instruction Transact-SQL.

L'instruction RECEIVE lit les messages d'une file d'attente et retourne un jeu de résultats. Le jeu de résultats retourné ne comporte aucune ligne ou plusieurs lignes, chacune contenant un message. Si la clause INTO n'est pas utilisée et que l'argument column_specifier n'affecte pas les valeurs des variables locales, l'instruction retourne un jeu de résultats au programme appelant.

L'instruction RECEIVE supprime les messages reçus de la file d'attente, sauf si la file d'attente spécifie une période de rétention des messages. Si la valeur ON est affectée au paramètre RETENTION, l'instruction RECEIVE met à jour la colonne status avec la valeur 1 et conserve les messages dans la file d'attente. Si une transaction contenant une instruction RECEIVE est restaurée, toutes les modifications apportées à la file d'attente dans la transaction sont également restaurées, et les messages retournent dans la file d'attente.

Tous les messages retournés par une instruction RECEIVE appartiennent au même groupe de conversations. L'instruction RECEIVE verrouille le groupe de conversations pour les messages retournés jusqu'à ce que la transaction contenant l'instruction se termine. Le jeu de résultats retourné par cette instruction est trié implicitement. Pour une conversation donnée, une instruction RECEIVE retourne les messages avec la valeur 1 affectée à la colonne status dans l'ordre croissant de l'argument message_sequence_number.

La clause WHERE de l'instruction RECEIVE contient uniquement des conditions de recherche utilisant conversation_handle ou conversation_group_id. La condition de recherche ne peut pas contenir les autres colonnes de la file d'attente. conversation_handle ou conversation_group_id ne peut pas être une expression. Si la clause WHERE est omise, l'instruction RECEIVE retourne les messages du groupe de conversations suivant disponible, quel que soit le verrou détenu par la connexion active sur d'autres groupes de conversations. Si l'argument conversation_handle est omis dans la clause WHERE, l'instruction RECEIVE retourne les messages du groupe de conversations quelle que soit la conversation à laquelle chaque message appartient. Si le handle de conversation ou l'identificateur du groupe de conversations spécifié dans la clause WHERE n'existe pas, ou s'il n'est pas associé à la file d'attente, l'instruction RECEIVE retourne une erreur.

Si l'état de la file d'attente spécifiée dans l'instruction RECEIVE a la valeur OFF, l'instruction échoue avec une erreur Transact-SQL.

Si la clause WAITFOR est spécifiée, l'instruction attend pendant la durée spécifiée ou jusqu'à ce qu'un jeu de résultats soit disponible. Si la file d'attente est supprimée ou si son état est défini sur OFF pendant l'attente de l'instruction, cette dernière retourne immédiatement une erreur. Si l'instruction RECEIVE spécifie un groupe de conversations ou un handle de conversation et que le service de cette conversation est supprimé ou déplacé vers une autre file d'attente, l'instruction RECEIVE génère une erreur Transact-SQL.

RECEIVE n'est pas valide dans une fonction définie par l'utilisateur.

Le tableau ci-après répertorie les colonnes d'une file d'attente.

Nom de colonne Type de données Description

status

tinyint

État du message. Pour les messages retournés par la commande RECEIVE, l'état a toujours la valeur 0. Les messages en file d'attente peuvent contenir une ou plusieurs des valeurs suivantes :

0= Prêt1= Message reçu2= Pas encore terminé3= Message envoyé conservé

priority

tinyint

0. Indiqué à titre d'information uniquement. Non pris en charge. La compatibilité future n'est pas garantie..

queuing_order

bigint

Numéro d'ordre des messages dans la file d'attente.

conversation_group_id

uniqueidentifier

Identificateur du groupe de conversations auquel ce message appartient.

conversation_handle

uniqueidentifier

Handle de conversation dont ce message fait partie.

message_sequence_number

bigint

Numéro de séquence du message dans la conversation.

NomService

nvarchar(512)

Nom du service auquel la conversation est destinée.

service_id

int

Identificateur d'objet SQL Server du service auquel la conversation est destinée.

service_contract_name

nvarchar(256)

Nom du contrat suivi par la conversation.

service_contract_id

int

Identificateur d'objet SQL Server du contrat suivi par la conversation.

message_type_name

nvarchar(256)

Nom du type de message qui décrit le message.

message_type_id

int

Identificateur d'objet SQL Server du type de message qui décrit le message.

validation

nchar(2)

Validation utilisée pour le message.

E = VideN = AucunX = XML

message_body

varbinary(MAX)

Contenu du message.

Autorisations

Pour recevoir un message, l'utilisateur en cours doit disposer de l'autorisation RECEIVE sur la file d'attente.

Exemple

A. Réception de toutes les colonnes de tous les messages d'un groupe de conversations

L'exemple suivant montre comment recevoir tous les messages disponibles du groupe de conversations suivant disponible dans la file d'attente ExpenseQueue. L'instruction retourne les messages en tant que jeu de résultats.

RECEIVE * FROM ExpenseQueue ;

A. Réception des colonnes spécifiées de tous les messages d'un groupe de conversations

L'exemple suivant montre comment recevoir tous les messages disponibles du groupe de conversations suivant disponible dans la file d'attente ExpenseQueue. L'instruction retourne les messages en tant que jeu de résultats qui contient les colonnes conversation_handle, message_type_name et message_body.

RECEIVE conversation_handle, message_type_name, message_body
FROM ExpenseQueue ;

C. Réception du premier message disponible de la file d'attente

L'exemple suivant montre comment recevoir le premier message disponible de la file d'attente ExpenseQueue en tant que jeu de résultats.

RECEIVE TOP (1) * FROM ExpenseQueue ;

D. Réception de tous les messages d'une conversation spécifique

L'exemple suivant montre comment recevoir tous les messages disponibles de la conversation spécifiée dans la file d'attente ExpenseQueue en tant que jeu de résultats.

DECLARE @conversation_handle UNIQUEIDENTIFIER ;

SET @conversation_handle = <retrieve conversation from database> ;

RECEIVE *
FROM ExpenseQueue
WHERE conversation_handle = @conversation_handle ;

E. Réception des messages d'un groupe de conversations spécifique

L'exemple suivant montre comment recevoir tous les messages disponibles du groupe de conversations spécifié dans la file d'attente ExpenseQueue en tant que jeu de résultats.

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. Réception dans une variable de table

L'exemple suivant montre comment recevoir tous les messages disponibles du groupe de conversations spécifié dans la file d'attente ExpenseQueue dans une variable de table.

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. Réception des messages et délai d'attente indéfini

L'exemple suivant montre comment recevoir tous les messages disponibles du groupe de conversations suivant disponible dans la file d'attente ExpenseQueue. L'instruction attend jusqu'à ce qu'un message soit disponible, puis retourne un jeu de résultats contenant toutes les colonnes de messages.

WAITFOR (
    RECEIVE *
    FROM ExpenseQueue) ;

H. Réception des messages et intervalle d'attente spécifié

L'exemple suivant montre comment recevoir tous les messages disponibles du groupe de conversations suivant disponible dans la file d'attente ExpenseQueue. L'instruction attend pendant 60 secondes ou au moins jusqu'à ce qu'un message soit disponible, en fonction de la première action qui se vérifie. L'instruction retourne un jeu de résultats contenant toutes les colonnes de messages si au moins un message est disponible. Dans le cas contraire, l'instruction retourne un jeu de résultats vide.

WAITFOR (
    RECEIVE *
    FROM ExpenseQueue ),
TIMEOUT 60000 ;

I. Réception de messages, modification du type d'une colonne

L'exemple suivant montre comment recevoir tous les messages disponibles du groupe de conversations suivant disponible dans la file d'attente ExpenseQueue. Si le type de message indique que le message contient un document XML, l'instruction convertit le corps du message en document 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. Réception d'un message, extraction de données du corps du message, récupération de l'état de la conversation

L'exemple suivant montre comment recevoir les messages disponibles suivants du groupe de conversations suivant disponible dans la file d'attente ExpenseQueue. Si le message est de type //Adventure-Works.com/Expenses/SubmitExpense, l'instruction extrait l'ID de l'employé et une liste d'éléments du corps du message. L'instruction récupère également l'état de la conversation dans la table 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 ;

Voir aussi

Référence

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)

Autres ressources

Didacticiels de Service Broker
Conversation Group Locks
Architecture des conversations

Aide et Informations

Assistance sur SQL Server 2005