Utilisation de notifications de requêtes

Les notifications de requêtes ont été introduites dans SQL Server 2005 et SQL Server Native Client. Basées sur l'infrastructure de Service Broker introduite dans SQL Server 2005, les notifications de requêtes permettent aux applications d'être notifiées en cas de modification des données. Cette fonctionnalité est particulièrement utile pour les applications qui fournissent un cache d'informations à partir d'une base de données, par exemple une application Web, et qui doivent être notifiées en cas de modification des données sources.

Les notifications de requêtes vous permettent de demander une notification dans un délai d'attente spécifié lorsque les données sous-jacentes d'une requête sont modifiées. La demande de notification spécifie les options de notification, notamment le nom du service, le texte du message et la valeur du délai d'attente au serveur. Les notifications sont remises par l'intermédiaire d'une file d'attente Service Broker qui peut être interrogée par les applications pour détecter les notifications disponibles.

La syntaxe de la chaîne des options des notifications de requêtes est la suivante :

service=<service-name>[;(local database=<database> | broker instance=<broker instance>)]

Par exemple :

service=mySSBService;local database=mydb

La durée de vie des abonnements aux notifications est supérieure à celle des processus qui les initialisent. Cela s'explique par le fait qu'une application peut créer un abonnement aux notifications, puis se terminer. L'abonnement reste valide, et la notification a lieu si les données sont modifiées dans le délai d'attente imparti spécifié au moment de la création de l'abonnement. Une notification est identifiée par la requête exécutée, les options de notification et le texte du message, et peut être annulée en attribuant la valeur 0 au délai d'attente.

Les notifications sont envoyées une seule fois. Pour une notification continue des modifications de données, un nouvel abonnement doit être créé en exécutant à nouveau la requête une fois chaque notification traitée.

Les applications SQL Server Native Client reçoivent en général des notifications en utilisant la commande Transact-SQLRECEIVE pour lire les notifications de la file d'attente associée au service spécifié dans les options de notification.

Notes

Les noms de tables doivent être qualifiés dans des requêtes pour lesquelles une notification est requise, par exemple dbo.myTable. Les noms de tables doivent être qualifiés avec des noms en deux parties. L'abonnement n'est pas valide si des noms en trois ou quatre parties sont utilisés.

L'infrastructure de notification repose sur une fonctionnalité de mise en file d'attente introduite dans SQL Server 2005. En général, les notifications générées au niveau du serveur sont envoyées par l'intermédiaire de ces files d'attente pour un traitement ultérieur. Pour plus d'informations sur la prise en charge des notifications de requêtes dans SQL Server, consultez Utilisation des notifications de requêtes.

Pour utiliser des notifications de requêtes, une file d'attente et un service doivent exister sur le serveur. Vous pouvez les créer à l'aide d'une instruction Transact-SQL semblable à la suivante :

CREATE QUEUE myQueue
CREATE SERVICE myService ON QUEUE myQueue 

([https://schemas.microsoft.com/SQL/Notifications/PostQueryNotification])

Notes

Le service doit utiliser le contrat prédéfini https://schemas.microsoft.com/SQL/Notifications/PostQueryNotification, comme indiqué plus haut.

Fournisseur OLE DB de SQL Server Native Client

Le fournisseur OLE DB de SQL Server Native Client prend en charge la notification du consommateur en cas de modification de l'ensemble de lignes. Le consommateur reçoit la notification à chaque phase de la modification de l'ensemble de lignes et à chaque tentative de modification.

Notes

Le passage d'une requête de notifications au serveur avec ICommand::Execute est la seule méthode valide pour s'abonner à des notifications de requête avec le fournisseur OLE DB de SQL Server Native Client.

Le jeu de propriétés DBPROPSET_SQLSERVERROWSET

Pour prendre en charge les notifications de requêtes par l'intermédiaire d'OLE DB, SQL Server Native Client ajoute les nouvelles propriétés suivantes au jeu de propriétés DBPROPSET_SQLSERVERROWSET.

Nom

Type

Description

SSPROP_QP_NOTIFICATION_TIMEOUT

VT_UI4

Nombre de secondes pendant lesquelles la notification de requête doit rester active.

La valeur par défaut est 432 000 secondes (5 jours). La valeur minimale est 1 seconde, et la valeur maximale est 2^31-1 secondes.

SSPROP_QP_NOTIFICATION_MSGTEXT

VT_BSTR

Texte du message de la notification. Il est défini par l'utilisateur et n'a aucun format prédéfini.

Par défaut, la chaîne est vide. Vous pouvez spécifier un message à l'aide de 1-2000 caractères.

SSPROP_QP_NOTIFICATION_OPTIONS

VT_BSTR

Options de notification de requêtes. Celles-ci sont spécifiées dans une chaîne avec la syntaxe nom=valeur. L'utilisateur est chargé de créer le service et de lire les notifications de la file d'attente.

La valeur par défaut est une chaîne vide.

L'abonnement aux notifications est toujours validé, que l'instruction ait été exécutée dans une transaction utilisateur ou en mode de validation automatique, ou que la transaction dans laquelle l'instruction s'est exécutée ait été validée ou restaurée. La notification du serveur est déclenchée lorsque l'une des conditions de notification non valides suivantes se produit : modification des données sous-jacentes ou du schéma ou expiration du délai d'attente imparti (selon l'opération qui se produit en premier). Les inscriptions de notification sont supprimées dès qu'elles sont déclenchées. Par conséquent, lorsque l'application reçoit des notifications, l'application doit encore s'abonner au cas où elle souhaiterait obtenir d'autres mises à jour.

Une autre connexion ou un autre thread peut vérifier la file d'attente de destination pour les notifications. Par exemple :

WAITFOR (RECEIVE * FROM MyQueue);   // Where MyQueue is the queue name. 

Notez que SELECT * ne supprime pas l'entrée de la file d'attente, contrairement à RECEIVE * FROM. Cela bloque un thread serveur si la file d'attente est vide. S'il existe des entrées de file d'attente au moment de l'appel, elles sont retournées immédiatement ; sinon, l'appel attend qu'une entrée de file d'attente soit soumise.

RECEIVE * FROM MyQueue

Cette instruction retourne immédiatement un jeu de résultats vide si la file d'attente est vide ; sinon, elle retourne toutes les notifications de la file d'attente.

Si SSPROP_QP_NOTIFICATION_MSGTEXT et SSPROP_QP_NOTIFICATION_OPTIONS ne sont pas NULL et ne sont pas vides, l'en-tête TDS de notifications de requêtes contenant les trois propriétés définies plus haut sont envoyées au serveur avec chaque exécution de la commande. Si l'un d'eux est NULL (ou vide), l'en-tête n'est pas envoyé et DB_E_ERRORSOCCURRED est déclenché (ou DB_S_ERRORSOCCURRED si les propriétés sont toutes deux marquées comme étant facultatives) et la valeur d'état est DBPROPSTATUS_BADVALUE. La validation se produit dans la phase de préparation et d'exécution. De la même façon, DB_S_ERRORSOCCURED est déclenché lorsque les propriétés de notification de requête sont définies pour les connexions sur les versions SQL Server avant SQL Server 2005. La valeur d'état dans ce cas est DBPROPSTATUS_NOTSUPPORTED.

L'initialisation d'un abonnement ne garantit pas que les messages suivants soient correctement remis. De plus, aucun contrôle n'est effectué en termes de validité du nom du service spécifié.

Notes

La préparation d'instructions ne provoque jamais l'initialisation de l'abonnement ; seule l'exécution d'instructions peut y parvenir et les notifications de requêtes ne sont pas concernées par l'utilisation des services principaux OLE DB.

Pour plus d'informations sur le jeu de propriétés DBPROPSET_SQLSERVERROWSET, consultez Propriétés et comportements de l'ensemble de lignes.

Pilote ODBC de SQL Server Native Client

Le pilote ODBC de SQL Server Native Client prend en charge les notifications de requêtes grâce à l'ajout de trois nouveaux attributs aux fonctions SQLGetStmtAttr et SQLSetStmtAttr :

  • SQL_SOPT_SS_QUERYNOTIFICATION_MSGTEXT

  • SQL_SOPT_SS_QUERYNOTIFICATION_OPTIONS

  • SQL_SOPT_SS_QUERYNOTIFICATION_TIMEOUT

Si SQL_SOPT_SS_QUERYNOTIFICATION_MSGTEXT et SQL_SOPT_SS_QUERYNOTIFICATION_OPTIONS ne sont pas NULL, l'en-tête TDS de notifications de requêtes contenant les trois attributs définis plus haut sera envoyé au serveur chaque fois que la commande est exécutée. Si l'un d'eux est NULL, l'en-tête n'est pas envoyé, et SQL_SUCCESS_WITH_INFO est retourné. La validation se produit sur SQLPrepare, SqlExecDirectet SqlExecute, qui échouent tous si les attributs ne sont pas valides. De la même façon, lorsque ces attributs de notification de requête sont définis pour les versions de SQL Server antérieures à SQL Server 2005, l'exécution échoue avec SQL_SUCCESS_WITH_INFO.

Notes

La préparation d'instructions ne provoque jamais l'initialisation de l'abonnement ; l'abonnement peut être initialisé par l'exécution d'instructions.

Cas particuliers et restrictions

Les types de données suivants ne sont pas pris en charge pour les notifications :

  • text

  • ntext

  • image

Si une demande de notification est soumise pour une requête qui retourne l'un de ces types, la notification se déclenche immédiatement en spécifiant que l'abonnement aux notifications n'était pas possible.

Si une demande d'abonnement est soumise pour un lot ou une procédure stockée, une demande d'abonnement séparée est soumise pour chaque instruction exécutée dans le traitement ou la procédure stockée. Les instructions EXECUTE n'inscrivent aucune notification mais la demande de notification est envoyée à la commande exécutée. S'il s'agit d'un lot, le contexte est appliqué aux instructions exécutées et les mêmes règles décrites ci-dessus sont appliquées.

La soumission d'une requête pour la notification qui a été soumise par le même utilisateur sous le même contexte de base de données et qui possède le même modèle, les mêmes valeurs de paramètre, la même ID de notification et le même emplacement de remise d'un abonnement actif existant, renouvellera l'abonnement existant en réinitialisant le nouveau délai d'attente spécifié. Cela signifie que si une notification est demandée pour des requêtes identiques, une seule notification est envoyée. Cette situation concerne une requête dupliquée dans un lot ou une requête dans une procédure stockée qui a été appelée plusieurs fois.