Поделиться через


Использование WQL с поставщиком WMI для событий сервера

Приложения для управления могут получать доступ к событиям SQL Server с помощью поставщика WMI для событий сервера путем выполнения инструкций WMI Query Language (WQL). WQL является упрощенным подмножеством языка SQL с некоторыми расширениями, специфичными для WMI. При использовании WQL приложение извлекает тип события из определенного экземпляра SQL Server, базы данных или объекта базы данных (в настоящее время поддерживаются только объекты очереди). Поставщик WMI для событий сервера преобразует запрос в уведомление о событии, создаваемое в целевой базе данных (в случае уведомлений о событиях, существующих в пределах базы данных или объекта) или в базе данных master (в случае уведомлений о событиях в пределах сервера).

Например, рассмотрим следующий WQL-запрос.

SELECT * FROM DDL_DATABASE_LEVEL_EVENTS WHERE DatabaseName = 'AdventureWorks'

На основе этого запроса поставщик WMI совершает попытку создать эквивалент этого уведомления о событии на целевом сервере.

USE AdventureWorks ;GOCREATE 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 могут указывать любые свойства событий, связанные с событием или его родительским событием. Полный список допустимых событий и свойств событий см. в разделе Поставщик инструментария WMI для классов событий и свойств сервера.

Следующий синтаксис WQL явно поддерживается поставщиком WMI для событий сервера. Может быть указан дополнительный синтаксис WQL, но он не указывается для этого поставщика и вместо этого анализируется службой узлов WMI. Дополнительные сведения о языке запросов WMI см. в документации по WQL на веб-узле MSDN.

Синтаксис

SELECT { event_property [ ,...n ] | * }FROM event_type WHERE where_condition 

Аргументы

  • event_property
    Свойство события. Например, PostTime, SPID и LoginName. Просмотрите каждое событие в списке поставщика инструментария WMI для классов событий и свойств сервера, чтобы узнать, какие свойства оно имеет. Например, событие DDL_DATABASE_LEVEL_EVENTS имеет свойства DatabaseName и UserName. Также оно наследует свойства SQLInstance, LoginName, PostTime, SPID и ComputerName от родительских событий.

  • ,...n
    Указывает, что event_property можно запрашивать несколько раз, разделяя запросы запятыми.

  • *
    Указывает, что запрашиваются все свойства, связанные с событием.

  • event_type
    Событие, для которого может быть создано уведомление. Список доступных событий см. в разделе Поставщик инструментария WMI для классов событий и свойств сервера. Следует иметь в виду, что имена event type соответствуют event_type | event_group, которые можно указать при создании вручную уведомления о событии с помощью инструкции CREATE EVENT NOTIFICATION. Примеры event type: 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 в наиболее узком возможном диапазоне. Если поставщику не удается выполнить регистрацию в наиболее узком диапазоне, он пытается выполнить ее в областях более высокого уровня, пока регистрация не пройдет успешно. Если достигнут самый высокий уровень (уровень сервера), и регистрация завершается сбоем, потребителю возвращается сообщение об ошибке.

Например, если в предложении WHERE указано DatabaseName='AdventureWorks', поставщик пытается зарегистрировать уведомление о событии в базе данных AdventureWorks. Если база данных AdventureWorks существует, и у вызывающего клиента достаточно разрешений для создания уведомления о событии в AdventureWorks, регистрация выполняется успешно. В противном случае выполняется попытка зарегистрировать уведомление о событии на уровне сервера. Регистрация выполняется успешно, если у клиента WMI достаточно разрешений. Однако в этом сценарии события не возвращаются клиенту, пока не будет создана база данных AdventureWorks.

where_condition также может действовать в качестве фильтра для дополнительного ограничения запроса к конкретной базе данных, схеме или объекту. Например, рассмотрим следующий WQL-запрос.

SELECT * FROM ALTER_TABLE WHERE DatabaseName = 'AdventureWorks' AND SchemaName = 'Sales'     AND ObjectType='Table' AND ObjectName = 'SalesOrderDetail'

В зависимости от результатов процесс регистрации, запрос WQL может быть зарегистрирован либо на уровне базы данных, либо на уровне сервера. Однако, даже если он зарегистрирован на уровне сервера, поставщик в конечном итоге отфильтровывает любые события ALTER_TABLE, неподходящие к таблице AdventureWorks.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. (Представление каталога должно иметь префикс с именем соответствующей базы данных.)

Примеры

A. Запросы событий на уровне сервера

Следующий запрос WQL извлекает все свойства событий для любого события трассировки SERVER_MEMORY_CHANGE, возникшего в экземпляре SQL Server.

SELECT * FROM SERVER_MEMORY_CHANGE

Б. Запросы событий на уровне базы данных

Следующий запрос WQL извлекает определенные свойства событий для любых событий, возникающих в базе данных AdventureWorks и существующих в группе событий DDL_DATABASE_LEVEL_EVENTS.

SELECT SPID, SQLInstance, DatabaseName FROM DDL_DATABASE_LEVEL_EVENTS WHERE DatabaseName = 'AdventureWorks' 

В. Запросы событий на уровне базы данных, фильтрация по схеме и объекту

Следующий запрос извлекает все свойства событий для любого события ALTER_TABLE, возникшего в таблице AdventureWorks.Sales.SalesOrderDetail.

SELECT * FROM ALTER_TABLE WHERE DatabaseName = 'AdventureWorks' AND SchemaName = 'Sales'     AND ObjectType='Table' AND ObjectName = 'SalesOrderDetail'