powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Распарсить SQL запрос
25 сообщений из 27, страница 1 из 2
Распарсить SQL запрос
    #40050334
Santa89
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть простой запрос

Код: sql
1.
DECLARE @Query VARCHAR(MAX) = 'SELECT * FROM Table t JOIN OtherTable ON t.id=OtherTable.t_id'



Как получить отсюда все используемые таблицы?
Т.е. получить ответ вида:

Table
OtherTable

Был подобный топик https://stackoverflow.com/questions/16692344/list-of-tables-used-in-an-sql-query но ответ оттуда почему-то не работает как надо, да и выполнять сам этот SQL запрос каждый раз для этого не очень хочется, теоретически таких может быть сотни.

Может быть кто-то знает более простые способы как правильно распарсить SQL запрос?
...
Рейтинг: 0 / 0
Распарсить SQL запрос
    #40050382
Фотография SQL2008
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Santa89,

вытаскивайте все слова после FROM и JOIN если не начинается на (.
... делов то на копейку
...
Рейтинг: 0 / 0
Распарсить SQL запрос
    #40050384
Гавриленко Сергей Алексеевич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SQL2008
Santa89,

вытаскивайте все слова после FROM и JOIN если не начинается на (.
... делов то на копейку
или merge
или delete

"Делов-то" немного, только если о простых селектах речь.
...
Рейтинг: 0 / 0
Распарсить SQL запрос
    #40050386
Агрох
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SQL2008,
Код: sql
1.
2.
3.
4.
5.
6.
SELECT * FROM DBName.TableName
SELECT * FROM "Da Ya Durak I Sozdal Takuyu Tablicu"
WITH R0 AS (
...
)
SELECT * FROM R0 //R0 - не таблица
...
Рейтинг: 0 / 0
Распарсить SQL запрос
    #40050388
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Объекты, затронутые запросом
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
declare @pss varchar(max) = '$connection = New-Object System.Data.SqlClient.SqlConnection("Data Source=%server%;Integrated Security=SSPI;Initial Catalog=%database%;");

$c1 = $connection.CreateCommand(); $c1.CommandText = "set showplan_xml on;";
$c2 = $connection.CreateCommand(); $c2.CommandText = "%query%";

$connection.Open();

$result = $c1.ExecuteNonQuery();
$r = $c2.ExecuteXmlReader();
$result = $r.Read();
$r.ReadOuterXml();
';

declare @query varchar(max) = 'select * from msdb..sysjobs a join msdb..sysjobsteps b on b.job_id = a.job_id';

set
 @pss = replace(replace(replace(replace(replace(@pss, '%server%', @@servername), '%database%', db_name()), '%query%', @query), nchar(10), ' '), nchar(13), ' ');

declare @command varchar(8000) = replace('powershell -command "%command%"', '%command%', replace(@pss, '"', '\"'));

declare @t table (s nvarchar(max));
insert into @t
 (s)
 exec xp_cmdshell @command;

declare @plan xml;
select
 @plan = cast(string_agg(s, '') as xml)
from
 @t
where
 s is not null;

with xmlnamespaces(default 'http://schemas.microsoft.com/sqlserver/2004/07/showplan')
select distinct
 t.n.value('@Database', 'sysname'),
 t.n.value('@Schema', 'sysname'),
 t.n.value('@Table', 'sysname')
from
 @plan.nodes('//Object') t(n);


ЗЫ: Правильную работу с временными таблицами допилите сами.
...
Рейтинг: 0 / 0
Распарсить SQL запрос
    #40050389
Фотография SQL2008
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гавриленко Сергей Алексеевич
SQL2008
Santa89,

вытаскивайте все слова после FROM и JOIN если не начинается на (.
... делов то на копейку
или merge
или delete

"Делов-то" немного, только если о простых селектах речь.

я подсказал путь, а частности сами определяйте
...
Рейтинг: 0 / 0
Распарсить SQL запрос
    #40050395
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SQL2008
я подсказал путь, а частности сами определяйте

А ещё могут быть cross/outer apply с таблицами внутри. А ещё у джойнов могут быть хинты соединения (inner loop join, например). А ещё inner/cartesian join могут быть заданы просто перечислением таблиц через запятую в секции from. Список этих "ещё" можно продолжать до бесконечности. Пусть получается достаточно трудоёмким - тянет на написание парсера SQL.
...
Рейтинг: 0 / 0
Распарсить SQL запрос
    #40050397
Santa89
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сон Веры Павловны
SQL2008
я подсказал путь, а частности сами определяйте

А ещё могут быть cross/outer apply с таблицами внутри. А ещё у джойнов могут быть хинты соединения (inner loop join, например). А ещё inner/cartesian join могут быть заданы просто перечислением таблиц через запятую в секции from. Список этих "ещё" можно продолжать до бесконечности. Пусть получается достаточно трудоёмким - тянет на написание парсера SQL.


это да!
но у меня все проще, эти запросы пишут аналитики, их надо распарсить, там из соединений будет максимум Apply, а в основном - простые селекты, простые Inner - Left джойны)
...
Рейтинг: 0 / 0
Распарсить SQL запрос
    #40050402
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Santa89,

студия парсит простые запросы, надо выделить запрос и "открыть в построителе".
...
Рейтинг: 0 / 0
Распарсить SQL запрос
    #40050455
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Можно попробовать создавать временную SP с этим запросом, потом запросить её зависимости через
Код: sql
1.
2.
select * from tempdb.sys.sql_expression_dependencies
    where referencing_id = object_id('tempdb..#temp_proc')
...
Рейтинг: 0 / 0
Распарсить SQL запрос
    #40050492
ShIgor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Santa89,

Код: sql
1.
select distinct source_database, source_schema, source_table from sys.dm_exec_describe_first_result_set ('SELECT * FROM Table t JOIN OtherTable ON t.id=OtherTable.t_id', null, 1)
...
Рейтинг: 0 / 0
Распарсить SQL запрос
    #40050498
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Попробовал воплотить свою мысль, вот так вот, похоже работает:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
declare @q nvarchar(max) = 'select * from products p join categories c on p.categoryid = c.categoryid'

declare @proc nvarchar(max)
set @proc = 'create procedure #temp_proc as ' + @q
exec sp_sqlexec @proc

select referenced_entity_name
  from tempdb.sys.sql_expression_dependencies
  where referencing_id = object_id('tempdb..#temp_proc')

drop procedure #temp_proc


referenced_entity_namecategoriesproducts
...
Рейтинг: 0 / 0
Распарсить SQL запрос
    #40050529
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Правильный путь, на самом деле, подсказал invm
Нужно получить план запроса в хml, а потом просто получить перечень упомянутых в нем таблиц.
Проблема в том, что инструкцию SET SHOWPLAN_XML ON не впихнешь в динамический запрос.
invm показал жутко интересный изврат :-)

Я в таком случае просто написал CLR функцию, который получала текст запроса, устанавливала SET SHOWPLAN_XML ON внутри себя и возвращал xml план.
...
Рейтинг: 0 / 0
Распарсить SQL запрос
    #40050543
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
uaggster
Я в таком случае просто написал CLR функцию, который получала текст запроса, устанавливала SET SHOWPLAN_XML ON внутри себя и возвращал xml план.

Ну вообще есть ещё вот такой вариант: 20058751 - как раз с использованием родного парсера SSMS. Правда, его всё равно придётся дорабатывать напильником - получать имена объектов конкатенацией TOKEN_ID, если они состоят из 2-3-4 частей, проверять, объекты ли это, а не CTE/подзапросы, итд итп.
...
Рейтинг: 0 / 0
Распарсить SQL запрос
    #40050590
Santa89
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ShIgor
Santa89,

Код: sql
1.
select distinct source_database, source_schema, source_table from sys.dm_exec_describe_first_result_set ('SELECT * FROM Table t JOIN OtherTable ON t.id=OtherTable.t_id', null, 1)



Хороший вариант, спасибо!
...
Рейтинг: 0 / 0
Распарсить SQL запрос
    #40050953
Фотография Критик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Santa89,

Лучше скажите - зачем?
Если ваяете data lineage, то:
1) обойтись таблицами зависимостей
2) динамику обработать отдельно, просто "сджойнив" её со списком таблиц (получите ложные совпадения, но довольно мало, если у вас имеется поддерживаемая система наименований)
...
Рейтинг: 0 / 0
Распарсить SQL запрос
    #40050971
L_argo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Santa89
ShIgor
Santa89,

Код: sql
1.
select distinct source_database, source_schema, source_table from sys.dm_exec_describe_first_result_set ('SELECT * FROM Table t JOIN OtherTable ON t.id=OtherTable.t_id', null, 1)

Хороший вариант, спасибо!
Хороший и простой. Но работает далеко не всегда. Н-р подзапросы не видит. Жаль.
...
Рейтинг: 0 / 0
Распарсить SQL запрос
    #40051019
Ролг Хупин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сон Веры Павловны
SQL2008
я подсказал путь, а частности сами определяйте

А ещё могут быть cross/outer apply с таблицами внутри. А ещё у джойнов могут быть хинты соединения (inner loop join, например). А ещё inner/cartesian join могут быть заданы просто перечислением таблиц через запятую в секции from. Список этих "ещё" можно продолжать до бесконечности. Пусть получается достаточно трудоёмким - тянет на написание парсера SQL.


ну, что вы, не усложняйте
"делов-то на копейку" (ц)
"я подсказал путь, а дальше допиливайте сами" (ц)
...
Рейтинг: 0 / 0
Распарсить SQL запрос
    #40051140
Фотография SQL2008
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ролг Хупин
Сон Веры Павловны
пропущено...

А ещё могут быть cross/outer apply с таблицами внутри. А ещё у джойнов могут быть хинты соединения (inner loop join, например). А ещё inner/cartesian join могут быть заданы просто перечислением таблиц через запятую в секции from. Список этих "ещё" можно продолжать до бесконечности. Пусть получается достаточно трудоёмким - тянет на написание парсера SQL.


ну, что вы, не усложняйте
"делов-то на копейку" (ц)
"я подсказал путь, а дальше допиливайте сами" (ц)



Ну если без пинка ходить не умеете, то вот второй волшебный пендель:

1. Собираете все имена, после FROM, JOIN, MERGE, USING ... их не так много, не надорветесь.
2. Выделяете только имя, без баз и схем. [DB].[dbo].[table] - > table
3. Удаляете все имена, которых нет в списке таблиц sys.tables.

Делов-то на 3 копейки.
...
Рейтинг: 0 / 0
Распарсить SQL запрос
    #40051145
Ролг Хупин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SQL2008
Ролг Хупин
пропущено...


ну, что вы, не усложняйте
"делов-то на копейку" (ц)
"я подсказал путь, а дальше допиливайте сами" (ц)



Ну если без пинка ходить не умеете, то вот второй волшебный пендель:

1. Собираете все имена, после FROM, JOIN, MERGE, USING ... их не так много, не надорветесь.
2. Выделяете только имя, без баз и схем. [DB].[dbo].[table] - > table
3. Удаляете все имена, которых нет в списке таблиц sys.tables.

Делов-то на 3 копейки.


Не нашел про синонимы, которых наверное не будет в sys.tables? и которые вообще могут быть реально в другой базе и даже на другом сервере.
Делов-то на 3 копейки(ц)
...
Рейтинг: 0 / 0
Распарсить SQL запрос
    #40051150
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SQL2008
Делов-то на 3 копейки.

Microsoft.SqlServer.Management.SqlParser.dll от последней редакции SSMS - почти 7 Мб скомпилированного в релизе кода.
...
Рейтинг: 0 / 0
Распарсить SQL запрос
    #40051156
Ролг Хупин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сон Веры Павловны
SQL2008
Делов-то на 3 копейки.

Microsoft.SqlServer.Management.SqlParser.dll от последней редакции SSMS - почти 7 Мб скомпилированного в релизе кода.


Можно, кстати, на шарпе найти , сделать SQLCLR процедуру, "делов-то на 3.5 копейки"
...
Рейтинг: 0 / 0
Распарсить SQL запрос
    #40051172
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ролг Хупин
Можно, кстати, на шарпе найти , сделать SQLCLR процедуру, "делов-то на 3.5 копейки"

Эта сборка и есть шарповая. Вопрос - в написании подобного в одно лицо "на 3 копейки".
...
Рейтинг: 0 / 0
Распарсить SQL запрос
    #40051277
Фотография SQL2008
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ролг Хупин
SQL2008
пропущено...


Ну если без пинка ходить не умеете, то вот второй волшебный пендель:

1. Собираете все имена, после FROM, JOIN, MERGE, USING ... их не так много, не надорветесь.
2. Выделяете только имя, без баз и схем. [DB].[dbo].[table] - > table
3. Удаляете все имена, которых нет в списке таблиц sys.tables.

Делов-то на 3 копейки.


Не нашел про синонимы, которых наверное не будет в sys.tables? и которые вообще могут быть реально в другой базе и даже на другом сервере.
Делов-то на 3 копейки(ц)

Видите!
Уже начали думать системно.
Уже начали продумывать детали.

Еще чуток и дозреете до SqlParser.dll.

Самый лучший способ заставить человека думать это разозлить его, вывести из состояния "а чё я могу? ничё не могу!" сказав "Да это проще пареной репы!". Это,если хотите, технотроллинг.

P.S. Был один русский профессор (кажется), так он давал ученикам заведомо невыполнимые задания, говорив при этом, что решение есть. Обманывал. Но любил смотреть как они рассуждают. Как отбрасывают неверные пути, как включают в рассмотрение любые варианты, анализируя их на предмет исполнения.
...
Рейтинг: 0 / 0
Распарсить SQL запрос
    #40051542
Ролг Хупин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сон Веры Павловны
Ролг Хупин
Можно, кстати, на шарпе найти , сделать SQLCLR процедуру, "делов-то на 3.5 копейки"

Эта сборка и есть шарповая. Вопрос - в написании подобного в одно лицо "на 3 копейки".


да, но я имел в виду в исходных кодах , чтобы можно было самому там докуролесить от души
...
Рейтинг: 0 / 0
25 сообщений из 27, страница 1 из 2
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Распарсить SQL запрос
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]