Текст запроса с помощью подсистемы расширенных событий Microsoft SQL

Опубликовал Александр Чернышов (HEKPOH) в раздел Программирование - Инструментарий

В будущем функция sys.fn_trace_gettable будет удалена из Microsoft SQL: http://msdn.microsoft.com/ru-ru/library/ms188425.aspx
Потому предлагаю вашему вниманию способ получения запроса T-SQL с помощью подсистемы расширенных событий

При написания обработки использовались:

1. типовая консоль запросов с диска ИТС

2. статьи по подсистеме расширенных событий: http://msdn.microsoft.com/ru-ru/library/bb630282.aspx

 

Некоторые функции по работе с сеансом расширенных событий

Результаты выводятся:

на закладке "Консоль запросов". В нижней части формы имеется панель со следующими страницами:

- "Результат", "Сводная таблица" - вывод результата запроса (функционал типовой консоли)

на закладке "Запрос SQL"

-  "Запрос SQL без псевдонимов" - текст запроса на T-SQL, полученный с помощью подсистемы расширенных событий

- "Запрос SQL с псевдонимами" - в тексте запроса на T-SQL заменены некоторые псевдонимы на "близкие глазу" одинэсника Smile Хотя, есть и более значимые причины для этого. Иногда приходится программисту, пишущему на T-SQL, показывать запросы из 1С, преобразованные в T-SQL. Увы, псевдонимы теряются.

- "Результат SQL без псевдонимов",  "Результат SQL с псевдонимами" - в разработке (выполнение SQL запроса из 1С и вывод результата в 1С без необходимости использовать SQL Server Management Studio - в разработке)

-  "Кольцевой буфер" - информационная страница, показывающая данные, собранные сеансом расширенных событий (с учетом ограничений, с которыми сеанс был создан).

 

Обработка вполне функциональная (хотя еще дописывается), в связи с чем хочу сразу предупредить о некоторых минусах:

1. не полностью переводятся в T-SQL пакетные запросы (в будущем будут)

2. изменяются только некоторые псевдонимы (основное направление развития - именно псевдонимы)

3. перед преобразованием запроса (нажатием на кнопку "SQL") текст запроса на 1С должен быть ОБЯЗАТЕЛЬНО отформатирован с помощью конструктора запроса

 

Некотрые использованные механизмы:

1. регулярные выражения

2. внедрение "маркера" в текст запроса 1С

 

Некоторые алгоритмы работы с сеансами расширенных событий:

Подготовка текстов SQL запросов:

Функция СоздатьИмяСеанса() Экспорт
	
	Возврат СтрЗаменить(Строка(Новый УникальныйИдентификатор()), "-", "");
	
КонецФункции	

// http://msdn.microsoft.com/ru-ru/library/bb677289%28v=sql.100%29.aspx
Функция Текст_СозданиеСеанса() Экспорт
	
	Текст =
	"CREATE EVENT SESSION ИмяСеанса ON SERVER 
	|ADD EVENT sqlserver.rpc_completed(SET collect_statement=(1)
	|	WHERE ([sqlserver].[database_name]=N'ИмяБД')),
	|ADD EVENT sqlserver.sql_statement_starting(SET collect_statement=(1)
	|   ACTION(package0.callstack,sqlserver.client_app_name,sqlserver.client_connection_id,sqlserver.client_hostname,sqlserver.client_pid)
	|	WHERE ([sqlserver].[database_name]=N'ИмяБД')) 
	|ADD TARGET package0.ring_buffer";
                                 	
	Текст = СтрЗаменить(Текст, "ИмяСеанса", ИмяСеанса);
	Текст = СтрЗаменить(Текст, "ИмяБД", 	ИмяБД);
	
	Возврат Текст;
	
КонецФункции

// http://msdn.microsoft.com/ru-ru/library/bb630257%28v=sql.100%29.aspx
Функция Текст_УдалениеСеанса() Экспорт
	
	Возврат "DROP EVENT SESSION " + ИмяСеанса + " ON SERVER";	
	
КонецФункции	

// http://msdn.microsoft.com/ru-ru/library/bb630368%28v=sql.100%29.aspx
Функция Текст_ЗапускСеанса() Экспорт
	
	Возврат "ALTER EVENT SESSION " + ИмяСеанса + " ON SERVER  STATE = START";	
	
КонецФункции

Функция Текст_ОстановкаСеанса() Экспорт
	
	Возврат "ALTER EVENT SESSION " + ИмяСеанса + " ON SERVER  STATE = STOP";	
	
КонецФункции

// http://msdn.microsoft.com/ru-ru/library/ff878182.aspx
Функция Текст_ПросмотрЦелевогоВывода() Экспорт
	
	Текст = 
	"SELECT --*** данный запрос получает текст кольцевого буфера ***-- 
	|	name, 
	|	target_name, 
	|	CAST(xet.target_data AS xml) AS Данные
	|FROM 
	|	sys.dm_xe_session_targets AS xet
	|JOIN sys.dm_xe_sessions AS xe ON (xe.address = xet.event_session_address)
	|WHERE 
	|	xe.name = 'ИмяСеанса'";
	
	Возврат СтрЗаменить(Текст, "ИмяСеанса", ИмяСеанса);
	
КонецФункции

 Пример вызова функции:

//удалим созданный сеанс
	Если УдалятьСеанс Тогда
		УдалениеСеанса = Текст_УдалениеСеанса(); 	
		Попытка
			ADOТаблица = Соединение.Execute(УдалениеСеанса);
		Исключение
			Сообщить("Не получилось удалить сеанс" + ИмяСеанса, СтатусСообщения.Важное);
			Возврат;
		КонецПопытки;
	Иначе
		//остановим сеанс (на всякий случай)
		ОстановкаСеанса = Текст_ОстановкаСеанса(); 
		Попытка
			ADOТаблица = Соединение.Execute(ОстановкаСеанса);
		Исключение
			Сообщить("Не получилось остановить сеанс " + ИмяСеанса, СтатусСообщения.Важное);
			Возврат;
		КонецПопытки;
	КонецЕсли;

Полученные тексты запросов (с псевдонимами и без) протестированы в среде SQL Server Management Studio

Скачать файлы

Наименование Файл Версия Размер
ЗапросSQL.epf
.epf 52,05Kb
13.06.13
50
.epf 52,05Kb 50 Скачать

См. также

Добавить вознаграждение
Комментарии
1. Иван Иванов (Famza) 80 10.06.13 09:21 Сейчас в теме
2. Сергей Тропин (sergant500) 12.06.13 10:29 Сейчас в теме
Картинка вместо обработки мешает полюбопытчинать тоже
3. Никита Грызлов (nixel) 71 12.06.13 11:44 Сейчас в теме
Спасибо за идею, покопаемся.
Под УФ, случаем, нет?
Будет время, попробую впилить в управляемую консоль...
4. Александр Чернышов (HEKPOH) 55 12.06.13 14:48 Сейчас в теме
Под УФ нет.
И обработка эта - именно, как идея. Как свободное время появляется, пишу-переписываю-дописываю :).
5. Илья Фамилия (m191) 112 13.06.13 09:38 Сейчас в теме
6. Александр Чернышов (HEKPOH) 55 13.06.13 11:36 Сейчас в теме
(2)(5) Извините, что-то я напутал с файлами:(
Вечерком залью обработку (с последними изменениями)
7. Александр Чернышов (HEKPOH) 55 13.06.13 18:31 Сейчас в теме
Описание обновил, скрины и обработку перезалил.
Еще раз, прошу прощения
8. Никита Грызлов (nixel) 71 14.06.13 10:37 Сейчас в теме
(7) HEKPOH, не получилось покопаться =)
Происходит что-то непонятное при попытке создания сеанса с предложением покурить (строка 907). Сервер доступен, имя базы корректное.

В Соединение.Errors лежит данная табличка на 4 ошибки:
Number	Source	Description	HelpFile	HelpContext	SQLState	NativeError
-2147217900	"Microsoft OLE DB Provider for SQL Server"	"Неправильный синтаксис около конструкции "066"."	""	0	"42000"	102
-2147217900	"Microsoft OLE DB Provider for SQL Server"	"Неправильный синтаксис около конструкции "EVENT"."	""	0	"42000"	102
-2147217900	"Microsoft OLE DB Provider for SQL Server"	"Неправильный синтаксис около конструкции "EVENT"."	""	0	"42000"	102
-2147217900	"Microsoft OLE DB Provider for SQL Server"	"Неправильный синтаксис около конструкции "TARGET"."	""	0	"42000"	102
...Показать Скрыть
9. Александр Чернышов (HEKPOH) 55 14.06.13 11:46 Сейчас в теме
nixel, привет.
Попробуем разобраться. Проверь по пунктам:
1. Уровень совместимости должен быть как на картинке или выше

2. Проверь, что пишет профайлер
3. Обнови драйвера OLE DB
10. Александр Чернышов (HEKPOH) 55 14.06.13 11:54 Сейчас в теме
Да, надеюсь название базы начинается не с цифры?
11. Александр Чернышов (HEKPOH) 55 14.06.13 12:39 Сейчас в теме
Может быть, дело в кавычках...

Попробуй в запрос создания сеанса вставить SET QUOTED_IDENTIFIER OFF
http://msdn.microsoft.com/ru-ru/library/ms174393.aspx
12. Никита Грызлов (nixel) 71 14.06.13 12:42 Сейчас в теме
(9) HEKPOH,
1) Совпадает.
2) Я не силен в администрировании sql-сервера. Можно пошаговую инструкцию или хотя бы где найти профайлер и ссылку на краткую инструкцию по использованию? Предоставлю все, что потребуется =)
3) Обновил. Результат тот же.

Имя базы начинается с буквы, наименование содержит строчные и заглавные латинские буквы и символы _ (подчеркивание)
13. Никита Грызлов (nixel) 71 14.06.13 12:43 Сейчас в теме
14. Никита Грызлов (nixel) 71 14.06.13 12:53 Сейчас в теме
(11) HEKPOH,
не помогло.
Заметил, что в первой строчке с ошибками текст постоянно меняется. Насколько я понял - это часть УИДа сеанса.

Еще иногда (1 раз на 10-15 попыток) вываливается такая ошибка:
Number	Source	Description	HelpFile	HelpContext	SQLState	NativeError
-2147217900	"Microsoft OLE DB Provider for SQL Server"	"Не удалось обнаружить объект атрибут событий или источник предиката, "sqlserver.database_name"."	""	0	"42000"	25 706

но не думаю, что это основная проблема в данном случае.
15. Александр Чернышов (HEKPOH) 55 14.06.13 12:57 Сейчас в теме
скопируй сюда (из отладчика) текст запроса (модуль объекта, строка 58)
16. Никита Грызлов (nixel) 71 14.06.13 13:14 Сейчас в теме
(15) HEKPOH,
SET QUOTED_IDENTIFIER OFF;

CREATE EVENT SESSION 8851d25ff3cd495da70b65b9f4257279 ON SERVER 
ADD EVENT sqlserver.rpc_completed(SET collect_statement=(1)
	WHERE ([sqlserver].[database_name]=N'grin_TOR_UV')),
ADD EVENT sqlserver.sql_statement_starting(SET collect_statement=(1)
   ACTION(package0.callstack,sqlserver.client_app_name,sqlserver.client_connection_id,sqlserver.client_hostname,sqlserver.client_pid)
	WHERE ([sqlserver].[database_name]=N'grin_TOR_UV')) 
ADD TARGET package0.ring_buffer
...Показать Скрыть


что с установкой флага QUOTED_IDENTIFIER, что без - результат и количество ошибок одинаковое.
17. Илья Фамилия (m191) 112 14.06.13 13:21 Сейчас в теме
у меня такая же фигня. 1) Ругается на GUID - добавил литерные символы спереди, стал ругаться так:
Сообщение 25706, уровень 16, состояние 8, строка 1
Не удалось обнаружить объект атрибут событий или источник предиката, "sqlserver.database_name".

CREATE
EVENT
SESSION session500b58c2577048aba868a255bd2891e7
ON SERVER
ADD EVENT sqlserver.rpc_completed(SET collect_statement=(1)
WHERE ([sqlserver].[database_name]=N'phis_im')),
ADD EVENT sqlserver.sql_statement_starting(SET collect_statement=(1)
ACTION(package0.callstack,sqlserver.client_app_name,sqlserver.client_connection_id,sqlserver.client_hostname,sqlserver.client_pid)
WHERE ([sqlserver].[database_name]=N'phis_im'))
ADD TARGET package0.ring_buffer

после вставки
SET QUOTED_IDENTIFIER OFF
НЕ ЗАРАБОТАЛО
18. Александр Чернышов (HEKPOH) 55 14.06.13 13:46 Сейчас в теме
(17) проверил в SQL Server Management Studio запрос из поста. Сеанс создается (естественно, имя базы заменил)


Вероятно, не хватает прав :(

У учетки, под которой коннектитесь, права sisadmin есть? Оно включает необходимое право CONTROL SERVER
19. Александр Чернышов (HEKPOH) 55 14.06.13 13:55 Сейчас в теме
m191, спасибо за слово "session" :)

nixel, m191, измените, пожл, функцию СоздатьИмяСеанса()
Возврат "ф" + СтрЗаменить(Строка(Новый УникальныйИдентификатор()), "-", "");
20. Никита Грызлов (nixel) 71 14.06.13 14:01 Сейчас в теме
(18) HEKPOH,
хм. у меня в обозревателе объектов нет ветви "Расширенные события". Это дополнительный компонент и его надо где-то включить?
Ну и в дополнение, на какой версии сервера Вы проверяете? У меня 2008 r2.
21. Александр Чернышов (HEKPOH) 55 14.06.13 14:19 Сейчас в теме
(20) у меня 2012, но!

у 2008 R2 с последним сервиспаком должны быть расширенные события
22. Никита Грызлов (nixel) 71 14.06.13 14:34 Сейчас в теме
Вооооот оно что. у меня первый сервис-пак. Что ж, буду трясти админа. спасибо!
23. Александр Чернышов (HEKPOH) 55 14.06.13 14:41 Сейчас в теме
(22) оч надеюсь на продолжение диалога по факту "тряски" админа :)
24. Илья Фамилия (m191) 112 14.06.13 14:59 Сейчас в теме
select @@VERSION
Microsoft SQL Server 2008 R2 (RTM) - 10.50.1600.1 (X64) Apr 2 2010 15:48:46 Copyright © Microsoft Corporation Standard Edition (64-bit) on Windows NT 5.2 <X64> (Build 3790: Service Pack 2)

Расширенных событий нет.
25. Александр Чернышов (HEKPOH) 55 14.06.13 15:09 Сейчас в теме
26. Никита Грызлов (nixel) 71 14.06.13 15:40 Сейчас в теме
(24) m191, (25) HEKPOH, последний сервис-пак на 2008 скуль - третий, не?
27. Александр Чернышов (HEKPOH) 55 14.06.13 15:52 Сейчас в теме
(26) не в курсе. у меня 2008 стоял без расширенных. как про них прочитал, 2012 поставил
28. Никита Грызлов (nixel) 71 14.06.13 16:42 Сейчас в теме
(23) HEKPOH, задача, так сказать, поставлена =)
А там посмотрим. Если разродится, то обязательно напишу о результатах.