2

我需要从表示 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

请记住,查询可能要复杂得多!

4

3 回答 3

3

如果不访问数据库,您无法确定查询中使用的的名称。

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

在不咨询数据库的情况下,这些对消费者是透明的。

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

于 2013-06-04T22:11:12.467 回答
1

您必须为以下程序集添加引用和指令:

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);
    }
}
于 2013-06-04T22:22:55.177 回答
0

您当然可以使用 SQL 解析器,如ANTLR,如本问答中所述,以获得对 SQL 的完整解析,然后提取表名。

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

于 2013-06-04T22:10:43.553 回答