- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
作为面向数据库的应用程序的一部分,我们发现有必要构造参数化查询并将其传递到其他 EntityFramework 应用程序中,通常用于桥接多个客户端数据库。我们通过非常标准的语法来做到这一点:
context.Database.SqlQuery<ReturnModel>(queryString, sqlParameters)
queryString 是一个字符串,sqlParameters 是一个 SqlParameter 对象数组。
当我们在应用程序中构建额外的自动化测试时,我发现将 SqlParser 用作“离线”测试器很有帮助。它不会捕获所有内容,但我可以:
var parseResults = Parser.Parse(queryString);
Assert.That(parseResults.Errors, Is.Empty);
并确保我们没有在参数化查询字符串中引入任何语法错误。
我还希望能够验证我们在生成的参数列表中没有任何遗漏的参数;查询字符串中预期的参数,但未提供。有什么方法可以将 sqlParameters 与 parseResults 中的内容进行匹配来执行此操作,或者利用 Microsoft.SqlServer.Management 库的其他功能?
最佳答案
SqlParser
是一个经典的解析器,带有用于处理结果的访问者界面。唯一美中不足的是公共(public)文档,它似乎与发布不同步,而且通常缺乏任何和所有示例,以至于它几乎没有用。我假设此处使用的解析器是您可以在 Microsoft.SqlServer.SqlParser
NuGet package 中找到的解析器。 .早期版本作为独立安装分发,它们不使用相同的类型。
首先,假设一个简单的查询,我们可以通过访问所有变量声明和引用并消除对局部声明变量的引用来获取所有参数的列表——这些必须是参数。
class ParameterVisitor : SqlCodeObjectRecursiveVisitor {
HashSet<string> referencedVariables = new HashSet<string>();
public override void Visit(SqlScalarVariableRefExpression codeObject) {
referencedVariables.Add(codeObject.VariableName);
}
HashSet<string> declaredVariables = new HashSet<string>();
public override void Visit(SqlVariableDeclaration codeObject) {
declaredVariables.Add(codeObject.Name);
}
public override void Visit(SqlBatch codeObject) {
base.Visit(codeObject);
parameters = referencedVariables.Except(declaredVariables).ToList();
}
List<string> parameters;
public IEnumerable<string> Parameters => parameters;
}
用作(例如):
internal static class ParseResultsExtensions {
public static IEnumerable<string> GetParameters(this ParseResult p) {
var pv = new ParameterVisitor();
p.Script.Accept(pv);
return pv.Parameters;
}
}
string queryString = @"DECLARE @notAParameter INT; SELECT @c, @b, @a, @notAParameter";
var myParameterCollection = new[] {
new SqlParameter("@a", SqlDbType.Int),
new SqlParameter("@b", SqlDbType.Int),
new SqlParameter("@c", SqlDbType.Int),
};
ParseResult parseResults = Parser.Parse(queryString);
Assert.That(parseResults.Errors, Is.Empty);
var expected = myParameterCollection.Select(p => p.ParameterName);
var actual = parseResults.GetParameters();
Assert.That(actual, Is.EquivalentTo(expected));
用信息量更大的断言调味。
令人沮丧的是,SqlScalarVariableRefExpression
有一个 BoundVariable
属性,它似乎能够将引用链接到它们的声明。不幸的是,使用它涉及使用 BinderProvider
,它从实际数据库中提取一整套元数据(因此它可以将标识符绑定(bind)到数据库对象)。关于这个的文档太少了,如果你只想做一些本地解析,我无法解码如何正确使用它。
这段代码也不完整,因为它只处理标量变量——添加对表变量的支持留给读者作为练习。
关于c# - 将 Array<SqlParameter> 匹配到 SqlParser.Parser 的输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54449987/
先看要解析的样例SQL语句: 复制代码 代码如下: select * from dual SELECT * frOm dual Select C1,c2 From tb select c1,c
当我在一台新机器上重建它时,我的 c# 安装程序项目出现了大量警告。这些警告类似于他们正在寻找 dll 的版本 11.0.0.0,其中只有版本 10.0.0.0 存在。我发现这是由于安装的 SQL S
背景 作为面向数据库的应用程序的一部分,我们发现有必要构造参数化查询并将其传递到其他 EntityFramework 应用程序中,通常用于桥接多个客户端数据库。我们通过非常标准的语法来做到这一点: c
我正在使用作为 Microsoft.SqlServer.Management.SqlParser.Parser 命名空间一部分的解析器来解析 Sql 语句,但是在测试时它工作正常; VSTS 中的构建
Parser 类只有返回 ParseResult 的方法 Parse,看来我对 ParseResult。我怎样才能得到我的 sql 语句的抽象语法树,或者只是可以从 sql 中解析元数据标记就可以了。
我是一名优秀的程序员,十分优秀!