Гость
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Распарсить SQL запрос / 25 сообщений из 27, страница 1 из 2
03.03.2021, 14:45
    #40050334
Santa89
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распарсить SQL запрос
Есть простой запрос

Код: 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
03.03.2021, 16:19
    #40050382
SQL2008
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распарсить SQL запрос
Santa89,

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

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

"Делов-то" немного, только если о простых селектах речь.
...
Рейтинг: 0 / 0
03.03.2021, 16:33
    #40050386
Агрох
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распарсить SQL запрос
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
03.03.2021, 16:44
    #40050388
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распарсить SQL запрос
Объекты, затронутые запросом
Код: 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
03.03.2021, 16:46
    #40050389
SQL2008
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распарсить SQL запрос
Гавриленко Сергей Алексеевич
SQL2008
Santa89,

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

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

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

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

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


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

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

Код: 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
04.03.2021, 08:13
    #40050529
uaggster
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распарсить SQL запрос
Правильный путь, на самом деле, подсказал invm
Нужно получить план запроса в хml, а потом просто получить перечень упомянутых в нем таблиц.
Проблема в том, что инструкцию SET SHOWPLAN_XML ON не впихнешь в динамический запрос.
invm показал жутко интересный изврат :-)

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

Ну вообще есть ещё вот такой вариант: 20058751 - как раз с использованием родного парсера SSMS. Правда, его всё равно придётся дорабатывать напильником - получать имена объектов конкатенацией TOKEN_ID, если они состоят из 2-3-4 частей, проверять, объекты ли это, а не CTE/подзапросы, итд итп.
...
Рейтинг: 0 / 0
04.03.2021, 11:34
    #40050590
Santa89
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распарсить SQL запрос
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
05.03.2021, 09:52
    #40050953
Критик
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распарсить SQL запрос
Santa89,

Лучше скажите - зачем?
Если ваяете data lineage, то:
1) обойтись таблицами зависимостей
2) динамику обработать отдельно, просто "сджойнив" её со списком таблиц (получите ложные совпадения, но довольно мало, если у вас имеется поддерживаемая система наименований)
...
Рейтинг: 0 / 0
05.03.2021, 10:22
    #40050971
L_argo
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распарсить SQL запрос
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
05.03.2021, 11:48
    #40051019
Ролг Хупин
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распарсить SQL запрос
Сон Веры Павловны
SQL2008
я подсказал путь, а частности сами определяйте

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


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

А ещё могут быть 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
05.03.2021, 18:08
    #40051145
Ролг Хупин
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распарсить SQL запрос
SQL2008
Ролг Хупин
пропущено...


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



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

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

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


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

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

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


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

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


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

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

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


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

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

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

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

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

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


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


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