Работа с уведомлениями запросов
Уведомления о запросах появились в SQL Server 2005 и в собственном клиенте SQL Server. С помощью уведомлений о запросах, построенных на основе инфраструктуры компонента Service Broker, представленной в SQL Server 2005, приложения могут получать извещения об изменениях данных. Эта функция особенно полезна для приложений, которые предоставляют кэш данных из базы данных (например, для веб-приложений), и которым требуются уведомления об изменении исходных данных.
С помощью уведомлений о запросах можно запрашивать уведомления в течение указанного времени ожидания при изменении базовых данных запроса. В запросе на уведомление указываются параметры уведомления, среди которых имя службы, текст сообщения и значение времени ожидания для сервера. Доставка уведомлений осуществляется через очередь компонента SQL Service Broker, которую приложения могут опрашивать на предмет имеющихся уведомлений.
Строка параметров уведомлений запросов имеет следующий синтаксис.
service=<service-name>[;(local database=<database> | broker instance=<broker instance>)]
Например:
service=mySSBService;local database=mydb
Подписки на уведомления переживают процесс, который их инициирует, поскольку приложение может создать подписку на уведомление, а затем завершиться. Подписка остается действительной, а уведомление будет отправлено в случае изменения данных в течение времени ожидания, указанного при создании подписки. Уведомление определяется выполненным запросом, параметрами уведомления, а также текстом сообщения. Его можно отменить, установив нуль в качестве значения времени ожидания.
Уведомления отправляются только один раз. Чтобы получать постоянные уведомления об изменении данных, необходимо создавать новую подписку после обработки каждого уведомления путем повторного выполнения запроса.
Приложения собственного клиента SQL Server обычно получают уведомления при помощи команды Transact-SQL RECEIVE, которая используется для чтения уведомлений из очереди, ассоциированной со службой (указанной в параметрах уведомления).
![]() |
---|
В запросах необходимо указывать имена таблиц, для которых требуется отправлять уведомления, например dbo.myTable. Имена таблиц должны состоять из двух частей. Подписка будет недействительной в случае использования трех- или четырехкомпонентных имен. |
Инфраструктура уведомлений построена поверх функции запросов, которая появилась в SQL Server 2005. Как правило, уведомления, формируемые на сервере, отправляются через эти запросы для последующей обработки.
Чтобы использовать уведомления о запросах, очередь и служба должны существовать на сервере. Их можно создать при помощи Transact-SQL следующим образом:
CREATE QUEUE myQueue
CREATE SERVICE myService ON QUEUE myQueue
([https://schemas.microsoft.com/SQL/Notifications/PostQueryNotification])
![]() |
---|
Служба должна использовать стандартный контракт https://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 добавляет в набор свойств DBPROPSET_SQLSERVERROWSET следующие новые свойства.
Название |
Тип |
Описание |
---|---|---|
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 |
Параметры уведомлений о запросах. Они указываются в строке с синтаксисом name=value. За создание службы и считывание уведомлений из очереди отвечает пользователь. Значением по умолчанию является пустая строка. |
Подписка на уведомления всегда фиксируется независимо от того, выполнялась ли инструкция в рамках пользовательской транзакции или в режиме 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. В этом случае значение состояния — 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, выполнение завершается неудачей с SQL_SUCCESS_WITH_INFO.
![]() |
---|
Подготовка инструкций никогда не вызывает запуска подписки; подписка может быть запущена выполнением инструкции. |
Особые случаи и ограничения
Следующие типы данных для уведомлений не поддерживаются:
text
ntext
image
Если сделан запрос на уведомление о запросе, который возвращает один из этих типов данных, уведомление срабатывает мгновенно с указанием, что выполнить подписку на уведомление невозможно.
Если запрос на подписку сделан для пакета или хранимой процедуры, для каждой инструкции, выполняемой в пакете или хранимой процедуре, будет сделан отдельный запрос на подписку. Инструкция EXECUTE не регистрирует уведомление, но направляет требование об уведомлении выполняемой команде. Если это пакет, к выполняемым инструкциям будет применен контекст и правила, описанные выше.
При подаче запроса на уведомление от того же пользователя в том же контексте базы данных, имеющего такой же шаблон, такие же значения параметров, такой же идентификатор уведомления и такое же расположение доставки, как у существующей активной подписки, существующая подписка будет обновлена с установкой вновь заданного времени ожидания. Это значит, что, если уведомление затребовано для одинаковых запросов, будет отправлено только одно уведомление. Данные условия применяются к запросам, повторяющимся в пакетах, или к запросам, которые вызываются несколько раз в хранимой процедуре.