TSql150Parser.Parse() 找不到错误

Posted

技术标签:

【中文标题】TSql150Parser.Parse() 找不到错误【英文标题】:TSql150Parser.Parse() does not find error 【发布时间】:2020-09-23 08:37:53 【问题描述】:

我正在尝试使用 TSql150Parser.Parse() 来验证 sql 查询 - 单元测试将检查查询。

我以:https://***.com/a/33834869/6836124 我目前的版本:https://dotnetfiddle.net/1Anhh9

相同的代码:

using Microsoft.SqlServer.TransactSql.ScriptDom;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
                    
public class Program

    public static void Main()
    
        var query = "DECLARE @NEW_VERSION_NUMBER int = 1;"+
                    "DECLARE @NEW_VERSION_NUMBER int = 1;";
        
        IList<string> errors;
        var result = query.IsValidSql(out errors);
        Console.WriteLine(result);
        Console.WriteLine(string.Join("; ", errors.ToArray()));
    


public static class SqlStringExtensions

    public static bool IsValidSql(this string query, out IList<string> errors)
    
        if (string.IsNullOrWhiteSpace(query)) throw new ArgumentNullException("asdasd");

        IList<ParseError> parseErrors;
        using (var reader = new StringReader(query))
        
            new TSql150Parser(false).Parse(reader, out parseErrors);
        
        errors = parseErrors.Select(err => err.Message).ToList();

        return !errors.Any();
    

我预计会出现错误:变量名称“@NEW_VERSION_NUMBER”已被声明 但实际上并没有错误。

为什么会跳过第一个错误?

【问题讨论】:

请将问题本身的相关代码作为minimal reproducible example,而不是稍后可能会中断的外部链接。而且您不会收到任何错误,因为解析器仅验证 syntactical 有效性。重新声明变量是非法的,这是一种语义属性,需要使用引擎执行它。这并不是 T-SQL 所特有的。在大多数语言中,语法层不负责变量范围。 即使该错误被捕获,也没有验证器可以捕获由错误的表和列名称或列不匹配导致的最重要的错误,因为它没有任何架构信息。这就像在没有实际类型定义的情况下尝试验证 C# 代码 如果您使用一个实际的(可能是空的)数据库,甚至可能是一个 LocalDB 实例来测试您的 SQL 代码,您会得到更有用的测试结果。您甚至可以将 T-SQL 单元测试与 tSQLt 一起使用 除了@PanagiotisKanavos 所说的之外,我已经成功地在构建管道中使用解析器来构建代码分析规则和容器来执行 tSQLt 单元测试。 感谢 tsqlt,但据我了解,tsqlt.org/user-guide 及其子页面 tsqlt 不适用于从 .net 框架项目中使用。我想验证 sql 查询作为拉取请求的构建过程的一部分——在这一步没有任何数据库。所以tsqlt不适合我。 【参考方案1】:

我将回答我自己的问题,并用我上次评论的副本结束它:

谢谢@JeroenMostert!似乎无法使用此解析器重新声明变量错误。我将尝试将sql验证(使用引擎)移至系统部署后的步骤。

【讨论】:

以上是关于TSql150Parser.Parse() 找不到错误的主要内容,如果未能解决你的问题,请参考以下文章

dateutil.parser.parse() 和丢失的时区信息

使用“import dateutil”和“dateutil.parser.parse()”时出现AttributeError,但使用“from dateutil import parser”时没有问题

TSQL 到 LINQ 转换参考?

python Stanford Parser Parse Sentence

如何检查 parser.parse_args() 中是不是支持特定参数? [复制]

python统一转换日期格式dateutil.parser.parse