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


Использование 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 = 'AdventureWorks2008R2'

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

USE AdventureWorks2008R2 ;
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 могут указывать любые свойства событий, связанные с событием или его родительским событием. Полный список допустимых событий и свойств событий см. в разделе Поставщик инструментария 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='База данных AdventureWorks2008R2', то поставщик пытается зарегистрировать уведомление о событии в базе данных База данных AdventureWorks2008R2. Если база данных База данных AdventureWorks2008R2 существует, а у вызывающего клиента достаточно разрешений для создания уведомления в ней, регистрация выполняется успешно. В противном случае выполняется попытка зарегистрировать уведомление о событии на уровне сервера. Регистрация выполняется успешно, если клиент WMI имеет необходимые разрешения. Однако в этом сценарии события не возвращаются клиенту, пока не будет создана база данных База данных AdventureWorks2008R2.

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

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

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

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

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

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

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