Получить используемые таблицы из SQL-запроса
Мне нужно извлечь из простой строки, представляющей SQL-запрос таблицы, которые используются в запросе без выполнения самого запроса в C#.
Пример:
string strQuery = "SELECT * FROM table1 LEFT JOIN (SELECT * FROM table2) tt WHERE tt.name IN (SELECT name FROM table3)";
ArrayList arrUsedTables = GetUsedTablesFromQuery(strQuery);
и после этой строки объект arrUsedTables
будет содержать:table1
,table2
,table3
Помните, что запрос может быть очень сложным!
3 ответа
Не заходя в БД, вы не можете знать наверняка имена таблиц, использованных в запросе.
Что если в вашем запросе используется представление или хранимая процедура?
Без обращения к базе данных они прозрачны для потребителя.
Единственный способ убедиться в этом - запросить список таблиц из базы данных и затем попытаться проанализировать их из встроенного sql.
Вам нужно будет добавить ссылки и директивы для следующих сборок:
using Microsoft.Data.Schema.ScriptDom;
using Microsoft.Data.Schema.ScriptDom.Sql;
using System.IO;
Затем вы можете создать GetUsedTablesFromQuery
метод:
private static ArrayList GetUsedTablesFromQuery(string strQuery)
{
var parser = new TSql100Parser(true);
IList<ParseError> errors = new List<ParseError>();
using (TextReader r = new StringReader(strQuery))
{
var result = parser.GetTokenStream(r, out errors);
var tables = result
.Select((i, index) => (i.TokenType == TSqlTokenType.From) ? result[index + 2].Text : null)
.Where(i => i != null)
.ToArray();
return new ArrayList(tables);
}
}
Конечно, вы можете использовать синтаксический анализатор SQL, такой как ANTLR, как описано в этом вопросе и ответе, чтобы получить полный анализ SQL, а затем извлечь имена таблиц.
Другой вариант - выполнить некоторый необработанный SQL, чтобы получить план выполнения запроса (используя инструкции здесь). План выполнения находится в XML, и затем вы можете использовать Linq to XML, чтобы запросить план для всех Table
атрибуты на любом ColumnReference
тег.