从sql查询中获取使用过的表

时间:2013-06-04 20:45:12

标签: c# 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将包含: table1table2table3

请记住,查询可能会非常复杂!

3 个答案:

答案 0 :(得分:3)

无需转到数据库,您无法确定查询中使用的表格的名称。

如果您的查询使用视图或存储过程怎么办?

如果不咨询数据库,这些对消费者来说是透明的。

唯一可以确定的方法是从数据库查询表列表,然后然后尝试从内联sql中解析它们。

答案 1 :(得分: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);
    }
}

答案 2 :(得分:0)

您可以使用ANTLR之类的SQL解析器,如this question and answer中所述,以获得SQL的完整解析,然后提取表名。

另一种选择是执行一些原始SQL以获取查询的执行计划(使用指令here)。执行计划采用XML格式,然后您可以使用Linq to XML查询任何Table标记上所有ColumnReference属性的计划。