【问题标题】:Why the AST created by Microsoft.SqlServer.Management.SqlParser.Parser for this query contains SqlTableValuedFunctionRefExpression?为什么 Microsoft.SqlServer.Management.SqlParser.Parser 为此查询创建的 AST 包含 SqlTableValuedFunctionRefExpression?
【发布时间】:2023-04-02 04:57:01
【问题描述】:

请注意以下简单查询:

SELECT ShortName FROM Groups (nolock)

我是这样解析的:

var parseResult = Parser.Parse("SELECT ShortName FROM Groups (nolock)");
Dump(parseResult.Script);

...

private static void Dump(string indent, SqlCodeObject sqlCodeObject)
{
    Console.WriteLine(indent + sqlCodeObject.GetType().Name);
    indent += "  ";
    foreach (var child in sqlCodeObject.Children)
    {
        Dump(indent, child);
    }
}

这会输出以下 AST:

SqlScript
  SqlBatch
    SqlSelectStatement
      SqlSelectSpecification
        SqlQuerySpecification
          SqlSelectClause
            SqlSelectScalarExpression
              SqlColumnRefExpression
                OnePartObjectIdentifier
                  SqlIdentifier
          SqlFromClause
            SqlTableValuedFunctionRefExpression
              OnePartObjectIdentifier
                SqlIdentifier
              SqlColumnRefExpression
                OnePartObjectIdentifier
                  SqlIdentifier

我的问题 - 为什么 SqlFromClauseSqlTableValuedFunctionRefExpression 的父级?我在查询中没有任何函数调用。

【问题讨论】:

  • 如果在提示前指定WITH关键字(即SELECT ShortName FROM Groups WITH (nolock)),是否得到预期结果。注意省略 WITH 已弃用。 FWIW,无论有没有WITH,使用Microsoft.SqlServer.TransactSql.ScriptDom 解析器对我来说都可以正常工作。
  • 这正是答案。如果没有with,解析器会认为调用了一个函数。我第一次使用 Microsoft.SqlServer.TransactSql.ScriptDom,但是 - stackoverflow.com/questions/69185651/… 使用 ScriptDom 解析器会阻止我在不失去理智的情况下调试代码。我不得不换。请安排您的评论作为答案。
  • @DanGuzman - 你会碰巧知道如何指示解析器尊重不推荐使用的语法,with 是可选的吗?

标签: sql-server parsing


【解决方案1】:

这是我可以通过使用 SMO 150.18208.0 获得所需结果的唯一设置组合:

var opts = new ParseOptions("GO", true, DatabaseCompatibilityLevel.Version80);
opts.TransactSqlVersion = TransactSqlVersion.Version105;

var parseResult = Parser.Parse("SELECT ShortName FROM Groups (nolock)", opts);
Dump("  ",parseResult.Script);

输出

SqlScript
    SqlBatch
      SqlSelectStatement
        SqlSelectSpecification
          SqlQuerySpecification
            SqlSelectClause
              SqlSelectScalarExpression
                SqlColumnRefExpression
                  OnePartObjectIdentifier
                    SqlIdentifier
            SqlFromClause
              SqlTableRefExpression
                OnePartObjectIdentifier
                  SqlIdentifier
                SqlTableHint

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-04
    • 1970-01-01
    • 1970-01-01
    • 2022-10-25
    • 1970-01-01
    • 1970-01-01
    • 2019-02-18
    相关资源
    最近更新 更多