Использование WQL с поставщиком WMI для событий сервера
Область применения: SQL Server
Приложения управления получают доступ к событиям SQL Server с помощью поставщика WMI для событий сервера путем выдачи инструкций WMI Language (WQL). WQL является упрощенным подмножеством языка SQL с некоторыми расширениями, специфичными для WMI. При использовании WQL приложение получает тип события для определенного экземпляра SQL Server, базы данных или объекта базы данных (единственный объект, поддерживаемый в настоящее время— очередь). Поставщик WMI для событий сервера преобразует запрос в уведомление о событии, созданное в целевой базе данных для уведомлений о событиях с областью действия базы данных или объектов, или в master
базе данных для уведомлений о событиях на уровне сервера.
Например, рассмотрим следующий WQL-запрос.
SELECT * FROM DDL_DATABASE_LEVEL_EVENTS WHERE DatabaseName = 'AdventureWorks2022'
На основе этого запроса поставщик WMI совершает попытку создать эквивалент этого уведомления о событии на целевом сервере.
USE AdventureWorks2022;
GO
CREATE EVENT NOTIFICATION SQLWEP_76CF38C1_18BB_42DD_A7DC_C8820155B0E9
ON DATABASE
WITH FAN_IN
FOR DDL_DATABASE_LEVEL_EVENTS
TO SERVICE
'SQL/Notifications/ProcessWMIEventProviderNotification/v1.0',
'A7E5521A-1CA6-4741-865D-826F804E5135';
GO
Аргумент в предложении FROM
WQL-запроса (DDL_DATABASE_LEVEL_EVENTS
) может представлять любое допустимое событие, о котором может быть создано уведомление. Аргументы в предложениях SELECT
и WHERE
могут указывать любые свойства событий, связанные с событием или его родительским событием. Список допустимых событий и свойств событий см. в разделе "Уведомления о событиях" (ядро СУБД).
Следующий синтаксис языка WQL явно поддерживается поставщиком WMI для событий сервера. Можно указать дополнительный синтаксис WQL, но он не предназначен для этого поставщика и анализируется службой узлов WMI. Дополнительные сведения о языке запросов WMI см. в документации по WQL на веб-узле MSDN.
Синтаксис
SELECT { event_property [ , ...n ] | * }
FROM event_type
WHERE where_condition
[ ; ]
Аргументы
event_property [ , ... n ] | *
Свойство события. Например, PostTime
, SPID
и LoginName
. Найдите каждое событие, указанное в поставщике WMI для классов и свойств событий сервера, чтобы определить, какие свойства он содержит. Например, событие DDL_DATABASE_LEVEL_EVENTS имеет свойства DatabaseName
и UserName
. Также оно наследует свойства SQLInstance
, LoginName
, PostTime
, SPID
и ComputerName
от родительских событий.
, ... n
Указывает, что event_property можно запрашивать несколько раз, разделенных запятыми.
*
Указывает, что запрашиваются все свойства, связанные с событием.
event_type
Любое событие, для которого можно создать уведомление о событии. Список доступных событий см. в разделе "Поставщик WMI" для классов и свойств событий сервера. Имена типов событий соответствуют тем же event_type event_group | , которые можно указать при создании уведомления о событии вручную с помощью.CREATE EVENT NOTIFICATION
Примеры типа события: CREATE_TABLE
, LOCK_DEADLOCK
и DDL_USER_EVENTS
TRC_DATABASE
.
Примечание.
Определенные системные хранимые процедуры, выполняющие DDL-подобные операции, могут также вызывать формирование уведомления о событиях. Протестируйте свои уведомления о событиях, чтобы определить их реакцию на системные хранимые процедуры. Например, CREATE TYPE
инструкция и sp_addtype
хранимая процедура будут запускать уведомление о событии, созданное в событии CREATE_TYPE
. Однако хранимая sp_rename
процедура не запускает уведомления о событиях. Дополнительные сведения см. в разделе "События DDL".
where_condition
Предикат WHERE
запроса предложения, состоящий из event_property имен и логических и операторов сравнения. Where_condition определяет область, в которой соответствующее уведомление о событии зарегистрировано в целевой базе данных. Он также может выступать в качестве фильтра для целевой схемы или объекта, из которого запрашивать event_type. Дополнительные сведения см. в разделе "Примечания".
Только операнд =
может использоваться вместе с DatabaseName
, SchemaName
и ObjectName
. Другие выражения нельзя использовать с этими свойствами события.
Замечания
Where_condition поставщика WMI для событий сервера определяет следующее:
Область, с помощью которой поставщик пытается получить указанные event_type: уровень сервера, уровень базы данных или уровень объекта (единственный объект, поддерживаемый в настоящее время, — очередь). В конечном счете эта область определяет тип уведомления о событии, создаваемого в базе данных-получателе. Этот процесс называется регистрацией уведомления о событии.
База данных, схема и объект (если применимо), в которых выполняется регистрация.
Поставщик WMI для событий сервера использует алгоритм снизу вверх, подходящий для создания максимально узкой области для базовой EVENT NOTIFICATION
среды. Алгоритм пытается свести к минимуму внутренние действия на сервере и сетевом трафике между экземпляром SQL Server и процессом узла WMI. Поставщик проверяет event_type , указанные в FROM
предложении, и условия в WHERE
предложении, и пытается зарегистрировать базовый EVENT NOTIFICATION
объект с максимальной возможной областью. Если поставщик не может зарегистрировать в самой узкой области, он пытается зарегистрировать в последовательно более высоких областях до тех пор, пока регистрация, наконец, не будет успешно выполнена. Если достигнут самый высокий уровень (уровень сервера), а регистрация завершается сбоем, возвращается сообщение об ошибке.
Например, если DatabaseName='AdventureWorks2022'
указано в WHERE
предложении, поставщик пытается зарегистрировать уведомление о событии AdventureWorks2022
в базе данных. Если база данных AdventureWorks2022
существует, а у вызывающего клиента достаточно разрешений для создания уведомления в AdventureWorks2022
, регистрация выполняется успешно. В противном случае выполняется попытка зарегистрировать уведомление о событии на уровне сервера. Регистрация выполняется успешно, если клиент WMI имеет необходимые разрешения. Однако в этом сценарии события не возвращаются клиенту, пока AdventureWorks2022
база данных не будет создана.
Where_condition также может выступать в качестве фильтра, чтобы дополнительно ограничить запрос определенной базой данных, схемой или объектом. Например, рассмотрим следующий WQL-запрос.
SELECT * FROM ALTER_TABLE
WHERE DatabaseName = 'AdventureWorks2022' AND SchemaName = 'Sales'
AND ObjectType='Table' AND ObjectName = 'SalesOrderDetail'
В зависимости от результата процесса регистрации этот запрос WQL может быть зарегистрирован на уровне базы данных или сервера. Однако даже если он зарегистрирован на уровне сервера, поставщик в конечном итоге фильтрует любые ALTER_TABLE
события, которые не применяются к Sales.SalesOrderDetail
таблице. Иными словами, поставщик возвращает только свойства событий ALTER_TABLE
, возникших в конкретной таблице.
Если указано составное выражение DatabaseName='AW1' OR DatabaseName='AW2'
, попытка зарегистрировать одно уведомление о событии в области сервера вместо двух отдельных уведомлений о событиях. Регистрация выполняется успешно, если вызывающий клиент имеет необходимые разрешения.
Если SchemaName='X' AND ObjectType='Y' AND ObjectName='Z'
все указано в WHERE
предложении, попытка зарегистрировать уведомление о событии непосредственно в объекте Z
в схеме X
. Регистрация выполняется успешно, если клиент имеет необходимые разрешения. В настоящее время события уровня объектов поддерживаются только в очередях и только для QUEUE_ACTIVATION
event_type.
Не все события можно запрашивать в любой конкретной области. Например, запрос WQL на событие трассировки, например Lock_Deadlock, или группу событий трассировки, например TRC_LOCKS
, можно зарегистрировать только на уровне сервера. Аналогичным образом CREATE_ENDPOINT
событие и DDL_ENDPOINT_EVENTS
группа событий также могут быть зарегистрированы только на уровне сервера. Дополнительные сведения о соответствующей области регистрации событий см. в разделе "Проектирование уведомлений о событиях". Попытка зарегистрировать WQL-запрос, event_type которого можно зарегистрировать только на уровне сервера, всегда выполняется на уровне сервера. Регистрация выполняется успешно, если клиент WMI имеет необходимые разрешения. Иначе клиенту возвращается ошибка. Однако в некоторых случаях предложение по-прежнему можно использовать WHERE
в качестве фильтра для событий на уровне сервера на основе свойств, соответствующих событию. Например, многие события трассировки имеют DatabaseName
свойство, которое можно использовать в предложении в WHERE
качестве фильтра.
Уведомления о событиях на уровне сервера создаются в master
базе данных и могут запрашиваться для метаданных с помощью представления каталога sys.server_event_notifications .
Уведомления о событиях с областью действия базы данных или объекта создаются в указанной базе данных и могут запрашиваться для метаданных с помощью представления каталога sys.event_notifications . Представление каталога должно иметь префикс с именем соответствующей базы данных.
Примеры
Примеры кода Transact-SQL в этой статье используют AdventureWorks2022
базу данных или AdventureWorksDW2022
пример базы данных, которую можно скачать с домашней страницы примеров и проектов сообщества Microsoft SQL Server.
А. Запрос событий в области сервера
Следующий запрос WQL извлекает все свойства события для любого SERVER_MEMORY_CHANGE
события трассировки, которое происходит в экземпляре SQL Server.
SELECT * FROM SERVER_MEMORY_CHANGE
B. Запрос событий в области базы данных
Следующий WQL-запрос получает конкретные свойства событий для любых событий, возникающих в базе данных AdventureWorks2022
и существующих в группе событий DDL_DATABASE_LEVEL_EVENTS
.
SELECT SPID, SQLInstance, DatabaseName FROM DDL_DATABASE_LEVEL_EVENTS
WHERE DatabaseName = 'AdventureWorks2022'
В. Запрос событий в области базы данных, фильтрация по схеме и объекту
Следующий запрос получает все свойства событий для любого события ALTER_TABLE
, возникшего в таблице Sales.SalesOrderDetail
.
SELECT * FROM ALTER_TABLE
WHERE DatabaseName = 'AdventureWorks2022' AND SchemaName = 'Sales'
AND ObjectType='Table' AND ObjectName = 'SalesOrderDetail'