【问题标题】:Get used tables from sql query [duplicate]从sql查询中获取使用过的表[重复]
【发布时间】:2014-09-10 08:37:59
【问题描述】:

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

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

【问题讨论】:

标签: c# sql


【解决方案1】:

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

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

无需咨询数据库,这些对消费者都是透明的。

唯一确定的方法是从数据库中查询表列表,然后然后尝试从您的内联 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);
        }
    }
    

    【讨论】:

    • Microsoft.Data.Schema.ScriptDom 已替换为 Microsoft.SqlServer.TransactSql.ScriptDom。我在C:\Program Files (x86)\Microsoft SQL Server\120\SDK\Assemblies\Microsoft.SqlServer.TransactSql.ScriptDom.dll 找到了 dll。 (使用新的命名空间/dll 时不需要 .Sql 命名空间。
    • 所以我试图让这个例子工作并遇到了一些问题,所以我想出了我自己的版本,我不能在这里发布,因为他们锁定了它(不是真正的重复,因为这个需要C# 但无论如何)。您可以在stackoverflow.com/a/25778275/641833 找到我的解决方案
    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 2011-04-25
      • 1970-01-01
      • 2015-11-13
      • 1970-01-01
      • 1970-01-01
      • 2023-02-25
      • 1970-01-01
      • 2020-01-15
      • 1970-01-01
      相关资源
      最近更新 更多