Работа с уведомлениями запросов

Применимо к:Управляемому экземпляру SQL Server Azure

Внимание

Собственный клиент SQL Server (часто сокращенный SNAC) был удален из SQL Server 2022 (16.x) и SQL Server Management Studio 19 (SSMS). Собственный клиент SQL Server (SQLNCLI или SQLNCLI11) и устаревший поставщик Microsoft OLE DB для SQL Server (SQLOLEDB) не рекомендуется для разработки новых приложений. Перейдите на новый драйвер Microsoft OLE DB (MSOLEDBSQL) для SQL Server или последний драйвер Microsoft ODBC для SQL Server . Сведения о SQLNCLI, которые поставляется в качестве компонента ядра СУБД SQL Server (версии 2012–2019), см. в этом исключении жизненного цикла поддержки.

Уведомления о запросах появились в SQL Server 2005 (9.x) и собственном клиенте SQL Server. На основе инфраструктуры Service Broker, представленной в SQL Server 2005 (9.x), уведомления запросов позволяют приложениям получать уведомления при изменении данных. Эта функция особенно полезна для приложений, которые предоставляют кэш данных из базы данных (например, для веб-приложений), и которым требуются уведомления об изменении исходных данных.

С помощью уведомлений о запросах можно запрашивать уведомления в течение указанного времени ожидания при изменении базовых данных запроса. В запросе на уведомление указываются параметры уведомления, среди которых имя службы, текст сообщения и значение времени ожидания для сервера. Доставка уведомлений осуществляется через очередь компонента SQL Service Broker, которую приложения могут опрашивать на предмет имеющихся уведомлений.

Строка параметров уведомлений запросов имеет следующий синтаксис.

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

Например:

service=mySSBService;local database=mydb

Подписки на уведомления переживают процесс, который их инициирует, поскольку приложение может создать подписку на уведомление, а затем завершиться. Подписка остается действительной, а уведомление будет отправлено в случае изменения данных в течение времени ожидания, указанного при создании подписки. Уведомление определяется выполненным запросом, параметрами уведомления, а также текстом сообщения. Его можно отменить, установив нуль в качестве значения времени ожидания.

Уведомления отправляются только один раз. Чтобы получать постоянные уведомления об изменении данных, необходимо создавать новую подписку после обработки каждого уведомления путем повторного выполнения запроса.

Приложения SQL Server Native Client обычно получают уведомления с помощью команды Transact-SQL RECEIVE для чтения уведомлений из очереди, связанной с службой, указанной в параметрах уведомлений.

Заметка

В запросах необходимо указывать имена таблиц, для которых требуется отправлять уведомления, например dbo.myTable. Имена таблиц должны состоять из двух частей. Подписка будет недействительной в случае использования трех- или четырехкомпонентных имен.

Инфраструктура уведомлений построена на основе функции очереди, представленной в SQL Server 2005 (9.x). Как правило, уведомления, формируемые на сервере, отправляются через эти запросы для последующей обработки.

Чтобы использовать уведомления о запросах, очередь и служба должны существовать на сервере. Их можно создать с помощью Transact-SQL, как показано ниже.

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

Заметка

Служба должна использовать стандартный контракт http://schemas.microsoft.com/SQL/Notifications/PostQueryNotification, показанный выше.

Поставщик OLE DB для собственного клиента SQL Server

Поставщик OLE DB собственного клиента SQL Server поддерживает уведомление потребителей об изменении набора строк. Потребитель получает уведомление на каждой стадии изменения набора строк, а также при каждой попытке внести изменение.

Заметка

Передача запроса уведомлений серверу с помощью ICommand::Execute является единственным допустимым способом подписки на уведомления запросов с помощью поставщика OLE DB собственного клиента SQL Server.

Набор свойств DBPROPSET_SQLSERVERROWSET

Для поддержки уведомлений запросов с помощью OLE DB sql Server Native Client добавляет следующие новые свойства в набор свойств DBPROPSET_SQLSERVERROWSET.

Имя Type Description
SSPROP_QP_NOTIFICATION_TIMEOUT VT_UI4 время в секундах, в течение которого уведомление запроса должно оставаться активным.

Значение по умолчанию — 432000 секунд (5 дней). Минимальное значение — 1 секунда, а максимальное значение — 2^31-1 секунд.
SSPROP_QP_NOTIFICATION_MSGTEXT VT_BSTR Текст сообщения уведомления. Определяется пользователем и не имеет стандартного формата.

По умолчанию эта строка пуста. В сообщении можно использовать от 1 до 2000 символов.
SSPROP_QP_NOTIFICATION_OPTIONS VT_BSTR параметры уведомлений о запросах. Эти параметры указываются в строке с использованием синтаксиса имя=значение. За создание службы и считывание уведомлений из очереди отвечает пользователь.

Значением по умолчанию является пустая строка.

Подписка на уведомления всегда фиксируется независимо от того, выполнялась ли инструкция в рамках пользовательской транзакции или в режиме AUTO COMMIT, а также была ли транзакция, в рамках которой выполнялась инструкция, зафиксирована либо был выполнен ее откат. Уведомление сервера срабатывает при возникновении любого из следующих недопустимых условий: изменение базовых данных или схемы либо по истечении времени ожидания, в зависимости от того, что произойдет первым. Регистрации уведомлений удаляются сразу же после их срабатывания. Поэтому, если приложению требуется получение уведомлений в дальнейшем, оно должно подписаться на них снова сразу после получения уведомления.

Другое соединение или поток может проверять целевую очередь на наличие уведомлений. Например:

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

Обратите внимание, что SELECT * не удаляет запись из очереди, однако функция RECEIVE * FROM выполняется. Если очередь пуста, поток сервера будет остановлен. При наличии в очереди записей в момент вызова они возвращаются мгновенно; в противном случае вызов ожидает появления записи в очереди.

RECEIVE * FROM MyQueue  

Если очередь пуста, то эта инструкция немедленно возвращает пустой результирующий набор; в противном случае она возвращает все уведомления в очереди.

Если значение свойств SSPROP_QP_NOTIFICATION_MSGTEXT и SSPROP_QP_NOTIFICATION_OPTIONS не равно NULL и не является пустым, то при каждом выполнении этой команды на сервер отправляется заголовок потока табличных данных уведомлений о запросах, содержащий три свойства, указанные выше. Если значение любого из них равно NULL (или пустое), заголовок не отправляется, а формируется DB_E_ERRORSOCCURRED (или DB_S_ERRORSOCCURRED, если оба свойства обозначены, как необязательные), а значение состояния устанавливается в DBPROPSTATUS_BADVALUE. Поверка выполняется в случае команды Execute/Prepare. Аналогичным образом, DB_S_ERRORSOCCURED возникает, когда свойства уведомления запроса задаются для подключений к версиям SQL Server до SQL Server 2005 (9.x). В этом случае значение состояния — DBPROPSTATUS_NOTSUPPORTED.

Запуск подписки не гарантирует успешной доставки последующих сообщений. Кроме того, допустимость указанного имени службы также не проверяется.

Заметка

При подготовке инструкций подписка никогда не запускается. Запуск подписки происходит только при выполнении инструкций, а использование базовых служб OLE DB не оказывает влияния на уведомления о запросах.

Дополнительные сведения о наборе свойств DBPROPSET_SQLSERVERROWSET см. в разделе "Свойства и поведение набора строк".

Драйвер ODBC для собственного клиента SQL Server

Драйвер ODBC собственного клиента SQL Server поддерживает уведомления о запросах с помощью добавления трех новых атрибутов в функции SQLGetStmtAttr и SQLSetStmtAttr :

  • Атрибут SQL_SOPT_SS_QUERYNOTIFICATION_MSGTEXT

  • SQL_SOPT_SS_QUERYNOTIFICATION_OPTIONS

  • SQL_SOPT_SS_QUERYNOTIFICATION_TIMEOUT

Если значение свойств SQL_SOPT_SS_QUERYNOTIFICATION_MSGTEXT и SQL_SOPT_SS_QUERYNOTIFICATION_OPTIONS не равно NULL, то при каждом выполнении этой команды на сервер отправляется заголовок потока табличных данных уведомлений о запросах, содержащий три атрибута, указанных выше. Если значение любого из них равно NULL, заголовок не отправляется и возвращается SQL_SUCCESS_WITH_INFO. Проверка выполняется в функции SQLPrepare, SqlExecDirect и SqlExecute, все из которых завершаются ошибкой, если атрибуты недопустимы. Аналогичным образом, если эти атрибуты уведомления запроса задаются для версий SQL Server до SQL Server 2005 (9.x), выполнение завершается сбоем с SQL_SUCCESS_WITH_INFO.

Заметка

Подготовка инструкций никогда не вызывает запуска подписки; подписка может быть запущена выполнением инструкции.

Особые случаи и ограничения

Следующие типы данных для уведомлений не поддерживаются:

  • text

  • ntext

  • Изображение

Если сделан запрос на уведомление о запросе, который возвращает один из этих типов данных, уведомление срабатывает мгновенно с указанием, что выполнить подписку на уведомление невозможно.

Если запрос на подписку сделан для пакета или хранимой процедуры, для каждой инструкции, выполняемой в пакете или хранимой процедуре, будет сделан отдельный запрос на подписку. Инструкция EXECUTE не регистрирует уведомление, но направляет требование об уведомлении выполняемой команде. Если это пакет, к выполняемым инструкциям будет применен контекст и правила, описанные выше.

Отправка запроса на уведомление, отправленное тем же пользователем в том же контексте базы данных, и имеет тот же шаблон, те же значения параметров, один и тот же идентификатор уведомления и то же расположение доставки существующей активной подписки, продлевает существующую подписку, сбросив новое указанное время ожидания. Это означает, что если уведомление запрашивается для идентичных запросов, будет отправлено только одно уведомление. Данные условия применяются к запросам, повторяющимся в пакетах, или к запросам, которые вызываются несколько раз в хранимой процедуре.

См. также

Компоненты собственного клиента SQL Server