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

Программирование - Инструментарий

В будущем функция 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
51
.epf 52,05Kb 51 Скачать

См. также

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

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

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

Имя базы начинается с буквы, наименование содержит строчные и заглавные латинские буквы и символы _ (подчеркивание)
13. Никита Грызлов (nixel) 142 14.06.13 12:43 Сейчас в теме
14. Никита Грызлов (nixel) 142 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) 64 14.06.13 12:57 Сейчас в теме
скопируй сюда (из отладчика) текст запроса (модуль объекта, строка 58)
16. Никита Грызлов (nixel) 142 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) 114 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) 64 14.06.13 13:46 Сейчас в теме
(17) проверил в SQL Server Management Studio запрос из поста. Сеанс создается (естественно, имя базы заменил)


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

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

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

у 2008 R2 с последним сервиспаком должны быть расширенные события
22. Никита Грызлов (nixel) 142 14.06.13 14:34 Сейчас в теме
Вооооот оно что. у меня первый сервис-пак. Что ж, буду трясти админа. спасибо!
23. Александр Чернышов (HEKPOH) 64 14.06.13 14:41 Сейчас в теме
(22) оч надеюсь на продолжение диалога по факту "тряски" админа :)
24. Илья Фамилия (m191) 114 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) 64 14.06.13 15:09 Сейчас в теме
26. Никита Грызлов (nixel) 142 14.06.13 15:40 Сейчас в теме
(24) m191, (25) HEKPOH, последний сервис-пак на 2008 скуль - третий, не?
27. Александр Чернышов (HEKPOH) 64 14.06.13 15:52 Сейчас в теме
(26) не в курсе. у меня 2008 стоял без расширенных. как про них прочитал, 2012 поставил
28. Никита Грызлов (nixel) 142 14.06.13 16:42 Сейчас в теме
(23) HEKPOH, задача, так сказать, поставлена =)
А там посмотрим. Если разродится, то обязательно напишу о результатах.
Оставьте свое сообщение