RECEIVE (Transact-SQL)

 

CETTE RUBRIQUE S’APPLIQUE À :ouiSQL Server (à partir de la version 2008)nonAzure SQL DatabasenonAzure SQL Data WarehousenonParallel Data Warehouse

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.

S’applique à: SQL Server (SQL Server 2008 jusqu’à version actuelle).

Topic link icon Conventions de la syntaxe Transact-SQL

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

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.

nom_colonne
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
Spécifie la file d'attente qui contient les messages à récupérer.

database_name
Nom de la base de données qui contient la file d'attente à partir de laquelle les messages sont envoyés. Lorsqu’aucun nom de base de données est fourni, les valeurs par défaut pour la base de données actuelle.

schema_name
Nom du schéma propriétaire de la file d'attente à partir de laquelle les messages sont envoyés. Lorsqu’aucun nom de schéma est fourni, les valeurs par défaut pour le schéma par défaut pour l’utilisateur actuel.

nom_file_attente
Nom de la file d'attente à partir de laquelle les messages sont envoyés.

DANS table_variable
Spécifie la variable de table dans laquelle RECEIVE place les messages. La variable de table doit avoir un nombre de colonnes égal à celui présent dans les messages. Le type de données de chaque colonne dans la variable de table doit pouvoir être converti implicitement vers le type de données de la colonne correspondante dans les messages. Si INTO n'est pas spécifié, les messages sont retournés sous la forme d'un jeu de résultats.

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. Le descripteur de conversation fourni doit être un uniqueidentifer, ou un type qui peut être converti en uniqueidentifier.

conversation_group_id = conversation_group_id
Spécifie le groupe de conversations pour les messages reçus. Le ID de groupe de conversation est fourni doit être un uniqueidentifier, ou un type convertible en uniqueidentifier.

Délai d’attente délai d’attente
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 n’est pas spécifiée ou que le délai d’expiration est de -1, le délai d’attente est illimité. Si le délai expire, l'instruction RECEIVE retourne un jeu de résultats vide.

System_CAPS_ICON_important.jpg Important


Si l'instruction RECEIVE n'est pas la première instruction dans un lot ou une procédure stockée, l'instruction précédente doit se terminer par un point-virgule (;).

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

Les messages retournés par l'instruction RECEIVE peuvent être de types différents. Les applications peuvent utiliser le message_type_name colonne pour router chaque message vers du code qui gère le type de message associé. Il existe deux classes de types de messages :

  • Les types de messages définis par l'application, qui ont été créés à l'aide de l'instruction CREATE MESSAGE TYPE. L'ensemble de types de messages définis par l'application autorisés dans une conversation est défini par le contrat Service Broker spécifié pour la conversation.

  • Messages système Service Broker qui retournent des informations d'état ou d'erreur.

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. Lorsque le paramètre de rétention pour la file d’attente est activée, l’instruction RECEIVE met à jour la état colonne 0 et conserve les messages dans la file d’attente. Quand une transaction qui contient 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 qui sont retournés jusqu'à ce que la transaction qui contient l'instruction se termine. Une instruction RECEIVE retourne les messages ayant une état de 1. Le jeu de résultats retourné par une instruction RECEIVE est trié implicitement :

  • Si des messages de plusieurs conversations rencontrent les conditions de clause WHERE, l'instruction RECEIVE retourne tous les messages d'une conversation avant de retourner les messages pour toute autre conversation. Les conversations sont traitées dans l'ordre descendant des niveaux de priorité.

  • Pour une conversation donnée, une instruction RECEIVE retourne les messages dans l’ordre croissant message_sequence_number order.

La clause WHERE de l’instruction RECEIVE peut contenir uniquement une condition de recherche qui utilise conversation_handle ou conversation_group_id. La condition de recherche ne peut pas contenir d'autres colonnes de la file d'attente. Le conversation_handle ou conversation_group_id ne peut pas être une expression. Le jeu de messages retourné dépend des conditions spécifiées dans la clause WHERE :

  • Si conversation_handle est spécifié, RECEIVE retourne tous les messages de la conversation spécifiée qui sont disponibles dans la file d’attente.

  • Si conversation_group_id est spécifié, RECEIVE retourne tous les messages qui sont disponibles dans la file d’attente à partir de toute conversation qui est membre du groupe de conversations spécifié.

  • En l'absence de clause WHERE, RECEIVE détermine quel groupe de conversations :

    • a un ou plusieurs messages dans la file d'attente ;

    • n'a pas été verrouillé par une autre instruction RECEIVE ;

    • a le niveau de priorité le plus élevé de tous les groupes de conversations qui répondent à ces critères.

    RECEIVE retourne ensuite tous les messages disponibles dans la file d'attente de toute conversation qui est un membre du groupe de conversations sélectionné.

Si le descripteur de conversation ou l'identificateur du groupe de conversations spécifié dans la clause WHERE n'existe pas ou n'est pas associé à la file d'attente spécifiée, l'instruction RECEIVE retourne une erreur.

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

Quand la clause WAITFOR est spécifiée, l'instruction attend pendant le délai spécifié 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 descripteur de conversation et que le service de cette conversation est supprimé ou déplacé vers une autre file d'attente, l'instruction RECEIVE signale une erreur Transact-SQL.

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

L'instruction RECEIVE n'a aucune prévention de privation de priorité. Si une instruction RECEIVE unique verrouille un groupe de conversations et extrait de nombreux messages à partir de conversations de faible priorité, aucun message ne peut être reçu de conversations de haute priorité dans le groupe. Pour empêcher ceci, lorsque vous extrayez des messages de conversations de faible priorité, utilisez la clause TOP pour limiter le nombre de messages extraits par chaque instruction RECEIVE.

Le tableau suivant répertorie les colonnes d'une file d'attente :

Nom de colonneType de donnéesDescription
étattinyintÉtat du message. Pour les messages renvoyés par la commande RECEIVE, l’état est toujours 0. Dans la file d'attente, les messages peuvent contenir l'une des valeurs suivantes :

 0= prêt1= message reçu2ne = pas encore terminé3= message envoyé conservé
prioritétinyintNiveau de priorité de conversation appliqué au message.
queuing_orderbigintNuméro d'ordre du message dans la file d'attente.
conversation_group_iduniqueidentifierIdentificateur du groupe de conversations auquel ce message appartient.
conversation_handleuniqueidentifierDescripteur de conversation dont ce message fait partie.
message_sequence_numberbigintNuméro de séquence du message dans la conversation.
SERVICE_NAMEnvarchar (512)Nom du service auquel la conversation est destinée.
service_idintIdentificateur d'objet SQL Server du service auquel la conversation est destinée.
service_contract_namenvarchar (256)Nom du contrat suivi par la conversation.
service_contract_idintIdentificateur d'objet SQL Server du contrat suivi par la conversation.
message_type_namenvarchar (256)Nom du type de message qui décrit le format du message. Les messages peuvent être des types de messages d'application ou des messages système Service Broker.
message_type_idintIdentificateur d'objet SQL Server du type de message décrivant le message.
validationNCHAR(2)Validation utilisée pour le message.

 E=EmptyN=NoneX=XML
message_bodyvarbinary (max)Contenu du message.

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

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 ;  

B. 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 reçoit tous les messages disponibles pour le groupe de conversations disponible suivant dans la ExpenseQueue file d’attente. L'instruction attend qu'au moins un message soit disponible, puis retourne un jeu de résultats qui contient toutes les colonnes des messages.

WAITFOR (  
    RECEIVE *  
    FROM ExpenseQueue) ;  

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

L’exemple suivant reçoit tous les messages disponibles pour le groupe de conversations disponible suivant dans la ExpenseQueue file d’attente. L'instruction attend 60 secondes ou qu'au moins un message soit disponible, selon ce qui se produit en premier. L'instruction retourne un jeu de résultats qui contient toutes les colonnes des 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 reçoit tous les messages disponibles pour le groupe de conversations disponible suivant dans la ExpenseQueue file d’attente. 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 ;  

BEGIN DIALOG CONVERSATION (Transact-SQL)
BEGIN CONVERSATION TIMER (Transact-SQL)
END CONVERSATION (Transact-SQL)
CRÉER le contrat (Transact-SQL)
CRÉER le TYPE DE MESSAGE (Transact-SQL)
ENVOI (Transact-SQL)
CRÉER la file d’attente (Transact-SQL)
MODIFIER la file d’attente (Transact-SQL)
SUPPRIMER la file d’attente (Transact-SQL)

Ajouts de la communauté

AJOUTER
Afficher: