Arbeiten mit Abfragebenachrichtigungen

Gilt für:SQL ServerAzure SQL Managed Instance

Wichtig

Der SQL Server Native Client (häufig abgekürzt mit SNAC) wurde aus SQL Server 2022 (16.x) und SQL Server Management Studio 19 (SSMS) entfernt. Der SQL Server Native Client (SQLNCLI oder SQLNCLI11) und der Microsoft OLE DB-Legacyanbieter für SQL Server (SQLOLEDB) werden für neue Anwendungsentwicklungen nicht empfohlen. Verwenden Sie in Zukunft den neuen Microsoft OLE DB-Treiber für SQL Server (MSOLEDBSQL) oder den neuesten Microsoft ODBC Driver for SQL Server. Informationen zu SQLNCLI, die als Komponente der SQL Server-Datenbank-Engine (Versionen 2012 bis 2019) enthalten ist, finden Sie in dieser Supportlebenszyklus-Ausnahme.

Abfragebenachrichtigungen wurden in SQL Server 2005 (9.x) und SQL Server Native Client eingeführt. Basierend auf der Service Broker-Infrastruktur, die in SQL Server 2005 (9.x) eingeführt wurde, ermöglichen Abfragebenachrichtigungen die Benachrichtigung von Anwendungen, wenn sich Daten geändert haben. Diese Funktion ist besonders nützlich für Anwendungen, die einen Informationscache aus einer Datenbank zur Verfügung stellen, z. B. eine Webanwendung, und die benachrichtigt werden müssen, wenn die Quelldaten geändert wurden.

Mit Abfragebenachrichtigungen können Sie eine Benachrichtigung innerhalb eines festgelegten Timeoutzeitraums anfordern, wenn sich die einer Abfrage zugrunde liegenden Daten ändern. Die Anforderung für die Benachrichtigung gibt die Benachrichtigungsoptionen an. Dazu gehören der Dienstname, der Meldungstext und der Timeoutwert für den Server. Benachrichtigungen werden durch eine Service Broker-Warteschlange übermittelt, von der Anwendungen verfügbare Benachrichtigungen abrufen können.

Die Syntax der Zeichenfolge für die Abfragebenachrichtigungsoptionen lautet:

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

Beispiel:

service=mySSBService;local database=mydb

Benachrichtigungsabonnements überdauern den Prozess, mit dem sie initiiert wurden, da eine Anwendung ein Benachrichtigungsabonnement erstellen und anschließend beendet werden kann. Das Abonnement bleibt gültig, und die Benachrichtigung wird gesendet, wenn die Daten innerhalb des während der Erstellung des Abonnements angegebenen Timeoutzeitraums geändert werden. Eine Benachrichtigung wird durch die ausgeführte Abfrage, die Benachrichtigungsoptionen und den Meldungstext identifiziert und wird möglicherweise abgebrochen, wenn der Timeoutwert auf NULL festgelegt wird.

Benachrichtigungen werden nur einmal gesendet. Für die kontinuierliche Benachrichtigung bei Datenänderungen müssen Sie ein neues Abonnement erstellen, indem Sie die Abfrage nach der Verarbeitung jeder Benachrichtigung erneut ausführen.

SQL Server Native Client Anwendungen erhalten in der Regel Benachrichtigungen mithilfe des Transact-SQL RECEIVE-Befehls, um Benachrichtigungen aus der Warteschlange zu lesen, die dem in den Benachrichtigungsoptionen angegebenen Dienst zugeordnet ist.

Hinweis

Tabellennamen müssen in Abfragen qualifiziert werden, für die Benachrichtigungen erforderlich sind, z. B. dbo.myTable. Tabellennamen müssen mit zwei Teilnamen qualifiziert werden. Das Abonnement ist ungültig, wenn drei oder vier Teilnamen verwendet werden.

Die Benachrichtigungsinfrastruktur setzt auf einer in SQL Server 2005 (9.x) eingeführten Queuing-Funktion auf. Im Allgemeinen werden auf dem Server generierte Benachrichtigungen durch diese Warteschlangen gesendet, um später verarbeitet zu werden.

Für die Verwendung von Abfragebenachrichtigungen ist eine Warteschlange und ein Dienst auf dem Server erforderlich. Diese können mit Transact-SQL wie folgt erstellt werden:

CREATE QUEUE myQueue  
CREATE SERVICE myService ON QUEUE myQueue   
  
([http://schemas.microsoft.com/SQL/Notifications/PostQueryNotification])  

Hinweis

Der Dienst muss den vordefinierten Vertrag http://schemas.microsoft.com/SQL/Notifications/PostQueryNotification verwenden wie oben dargestellt.

SQL Server Native Client OLE DB-Anbieter

Der SQL Server Native Client OLE DB-Anbieter unterstützt Consumerbenachrichtigungen bei Rowsetänderungen. Der Consumer erhält in jeder Phase der Rowsetänderung und bei jeder versuchten Änderung eine Benachrichtigung.

Hinweis

Das Übergeben einer Benachrichtigungsabfrage an den Server mit ICommand::Execute ist die einzige gültige Möglichkeit, Abfragebenachrichtigungen mit dem SQL Server Native Client OLE DB-Anbieter zu abonnieren.

Die DBPROPSET_SQLSERVERROWSET-Eigenschaftsgruppe

Um Abfragebenachrichtigungen über OLE DB zu unterstützen, fügt SQL Server Native Client dem DBPROPSET_SQLSERVERROWSET-Eigenschaftensatz die folgenden neuen Eigenschaften hinzu.

Name type BESCHREIBUNG
SSPROP_QP_NOTIFICATION_TIMEOUT VT_UI4 Die Anzahl der Sekunden, die die Abfragebenachrichtigung aktiv bleiben soll.

Der Standardwert ist 432000 Sekunden (5 Tage). Der Mindestwert ist 1 Sekunde und der Höchstwert 2^31-1 Sekunden.
SSPROP_QP_NOTIFICATION_MSGTEXT VT_BSTR Der Text der Benachrichtigung. Dieser ist benutzerdefiniert und weist kein vordefiniertes Format auf.

Standardmäßig ist die Zeichenfolge leer. Sie können eine Meldung mit 1-2000 Zeichen angeben.
SSPROP_QP_NOTIFICATION_OPTIONS VT_BSTR Die Abfragebenachrichtigungsoptionen. Diese werden in einer Zeichenfolge mit der Syntax name=value angegeben. Der Benutzer ist für das Erstellen des Diensts und Lesen von Benachrichtigungen von der Warteschlange verantwortlich.

Der Standardwert ist eine leere Zeichenfolge.

Für das Benachrichtigungsabonnement wird immer ein Commit durchgeführt, unabhängig davon, ob die Anweisung in einer Benutzertransaktion oder im Autocommitmodus ausgeführt wurde oder ob für die Transaktion, in der die Anweisung ausgeführt wurde, ein Commit oder Rollback durchgeführt wurde. Die Serverbenachrichtigung wird bei einer der folgenden unzulässigen Benachrichtigungsbedingungen ausgelöst: bei einer Änderung der zugrunde liegenden Daten oder des zugrunde liegenden Schemas oder bei Erreichung des Timeoutzeitraums, je nachdem, welches Ereignis früher eintritt. Benachrichtigungsregistrierungen werden gelöscht, sobald sie ausgelöst wurden. Nach dem Empfang von Benachrichtigungen muss die Anwendung das Abonnement erneuern für den Fall, dass weitere Updates abgerufen werden sollen.

Eine andere Verbindung oder ein Thread kann die Zielwarteschlange auf Benachrichtigungen überprüfen. Beispiel:

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

Beachten Sie, dass SELECT * den Eintrag in der Warteschlange nicht löscht, RECEIVE * FROM jedoch schon. Dadurch wird ein Serverthread blockiert, wenn die Warteschlange leer ist. Wenn zum Zeitpunkt des Aufrufs Warteschlangeneinträge vorhanden sind, werden sie unmittelbar zurückgegeben. Andernfalls wartet der Aufruf, bis ein Warteschlangeneintrag vorgenommen wird.

RECEIVE * FROM MyQueue  

Diese Anweisung gibt unverzüglich ein leeres Resultset zurück, wenn die Warteschlange leer ist. Andernfalls gibt sie alle Warteschlangenbenachrichtigungen zurück.

Wenn SSPROP_QP_NOTIFICATION_MSGTEXT und SSPROP_QP_NOTIFICATION_OPTIONS nicht NULL und nicht leer sind, wird der TDS-Abfragebenachrichtigungsheader mit den drei oben definierten Eigenschaften bei jeder Ausführung des Befehls an den Server gesendet. Wenn einer der Werte NULL (oder leer) ist, wird der Header nicht gesendet und DB_E_ERRORSOCCURRED ausgelöst (oder DB_S_ERRORSOCCURRED, wenn die Eigenschaften beide als optional gekennzeichnet sind). Der Statuswert wird auf DBPROPSTATUS_BADVALUE festgelegt. Die Überprüfung wird bei Ausführen/Vorbereiten vorgenommen. Ebenso wird DB_S_ERRORSOCCURED ausgelöst, wenn die Abfragebenachrichtigungseigenschaften für Verbindungen mit SQL Server Versionen vor SQL Server 2005 (9.x) festgelegt sind. In diesem Fall ist der Statuswert DBPROPSTATUS_NOTSUPPORTED.

Ein Abonnement zu initiieren gewährleistet nicht, dass nachfolgende Meldungen erfolgreich übermittelt werden. Außerdem wird keine Prüfung im Hinblick auf die Gültigkeit des angegebenen Dienstnamens durchgeführt.

Hinweis

Durch Vorbereiten der Anweisungen wird nie eine Initiierung des Abonnements ausgelöst. Dies wird nur durch die Ausführung der Anweisung erreicht. Abfragebenachrichtigungen werden von der Verwendung von OLE DB-Basisdiensten nicht beeinflusst.

Weitere Informationen zum DBPROPSET_SQLSERVERROWSET Eigenschaftensatz finden Sie unter Rowseteigenschaften und -verhalten.

ODBC-Treiber für SQL Server Native Client

Der SQL Server Native Client ODBC-Treiber unterstützt Abfragebenachrichtigungen durch das Hinzufügen von drei neuen Attributen zu den Funktionen SQLGetStmtAttr und SQLSetStmtAttr:

  • SQL_SOPT_SS_QUERYNOTIFICATION_MSGTEXT

  • SQL_SOPT_SS_QUERYNOTIFICATION_OPTIONS

  • SQL_SOPT_SS_QUERYNOTIFICATION_TIMEOUT

Wenn SQL_SOPT_SS_QUERYNOTIFICATION_MSGTEXT und SQL_SOPT_SS_QUERYNOTIFICATION_OPTIONS nicht NULL sind, wird der TDS-Abfragebenachrichtigungsheader mit den drei oben definierten Attributen bei jeder Ausführung des Befehls an den Server gesendet. Wenn eine der Eigenschaften NULL ist, wird der Header nicht gesendet und SQL_SUCCESS_WITH_INFO zurückgegeben. Die Überprüfung erfolgt für die SQLPrepare-Funktion, SqlExecDirect und SqlExecute, die alle fehlschlagen, wenn die Attribute ungültig sind. Wenn diese Abfragebenachrichtigungsattribute für SQL Server Versionen vor SQL Server 2005 (9.x) festgelegt sind, schlägt die Ausführung mit SQL_SUCCESS_WITH_INFO fehl.

Hinweis

Durch Vorbereiten der Anweisungen wird nie eine Initiierung des Abonnements ausgelöst. Das Abonnement kann nur durch die Anweisungsausführung initiiert werden.

Sonderfälle und Einschränkungen

Die folgenden Datentypen werden für Benachrichtigungen nicht unterstützt:

  • text

  • ntext

  • image

Wenn eine Benachrichtigungsanforderung für eine Abfrage gesendet wird, die einen dieser Typen zurückgibt, wird die Benachrichtigung sofort mit dem Hinweis ausgelöst, dass das Benachrichtigungsabonnement nicht möglich sei.

Wenn eine Abonnementanforderung für einen Batch oder eine gespeicherte Prozedur erfolgt, wird für jede Anweisung, die innerhalb des Batches oder der gespeicherten Prozedur ausgeführt wird, eine separate Abonnementanforderung ausgegeben. EXECUTE-Anweisungen registrieren keine Benachrichtigung, sondern senden die Benachrichtigungsanforderung an den ausgeführten Befehl. Wenn es sich um einen Batch handelt, wird der Kontext auf die ausgeführten Anweisungen angewendet, und es gelten die gleichen Regeln wie oben beschrieben.

Die Übermittlung einer Abfrage für Benachrichtigungen, die vom gleichen Benutzer unter demselben Datenbankkontext übermittelt wurde und dieselbe Vorlage, dieselben Parameterwerte, dieselbe Benachrichtigungs-ID und denselben Übermittlungsort eines vorhandenen aktiven Abonnements aufweist, wird das vorhandene Abonnement erneuert und das neu angegebene Timeout zurückgesetzt. Das bedeutet, dass nur eine Benachrichtigung gesendet wird, wenn eine Benachrichtigung für identische Abfragen angefordert wird. Dies gilt sowohl für Abfragen, die in einem Batch dupliziert werden, als auch für Abfragen in einer gespeicherten Prozedur, die mehrmals aufgerufen wurde.

Weitere Informationen

SQL Server Native Client-Funktionen