2013-06-04 4 views
2

Мне нужно извлечь из простой строки, которые представляют sql-запрос таблицы, которые используются в запросе, без выполнения самого запроса в C#.Использовать таблицы из sql-запроса

Пример:

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

Помните, что запрос может быть намного сложнее!

+2

Что ahve вы пробовали до сих пор? – David

+0

Я бы предложил использовать регулярное выражение, однако .... http://stackoverflow.com/a/281059/284240 –

+2

Вам нужен парсер SQL для .Net: http://stackoverflow.com/questions/76083/parsing- sql-in-net –

ответ

0

Вы можете использовать синтаксический анализатор SQL, такой как ANTLR, как описано в this question and answer, чтобы получить полный анализ SQL, а затем извлечь имена таблиц.

Другим вариантом является выполнение некоторого необработанного SQL для получения плана выполнения запроса (с использованием инструкций here). План выполнения находится в XML, а затем вы можете использовать Linq для XML для запроса плана для всех атрибутов Table на любом теге ColumnReference.

3

Не вдаваясь в БД вы не можете знать наверняка имена таблиц, используемых в запросе.

Что делать, если ваш запрос использует представление или хранимую процедуру?

Без консультации с базой данных они прозрачны для потребителя.

Единственный способ быть уверенным в том, чтобы запросить список таблиц из базы данных и , затем, чтобы попытаться проанализировать их из встроенного sql.

2

Вы должны добавить ссылки и директивы для следующих узлов:

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); 
    } 
} 
+0

Microsoft.Data.Schema .ScriptDom был заменен на [Microsoft.SqlServer.TransactSql.ScriptDom] (http://stackoverflow.com/questions/17013135/microsoft-data-schema-scriptdom-with-vs2012-ultimate). Я нашел dll в 'C: \ Program Files (x86) \ Microsoft SQL Server \ 120 \ SDK \ Assemblies \ Microsoft.SqlServer.TransactSql.ScriptDom.dll'. (Вам не нужно пространство имен .Sql при использовании нового пространства имен/dll. – Trisped

+0

Итак, я попытался заставить пример работать и столкнулся с рядом проблем, поэтому я придумал свою собственную версию, которую я не могу опубликовать здесь, так как они ее заблокировали (на самом деле это не дуп, так как для этого требуется C#, но что угодно). Вы можете найти мое решение по адресу http://stackoverflow.com/a/25778275/641833 – Trisped

Смежные вопросы