如何以编程方式检查(解析)SQL 语句的有效性?
Posted
技术标签:
【中文标题】如何以编程方式检查(解析)SQL 语句的有效性?【英文标题】:How can I programmatically check (parse) the validity of a TSQL statement? 【发布时间】:2011-03-06 06:59:42 【问题描述】:我正在尝试使我的集成测试更具幂等性。一个想法是在每次测试后执行回滚,另一个想法是如何以编程方式解析文本,类似于查询分析器或 SSMS 中的绿色复选框。
如何让 SQL Server 解析我的命令而不使用 ADO.NET 运行它?
更新: 这就是最终如愿以偿的工作:
using (DbCommand executeOnly = Factory.DbCommand())
executeOnly.Connection = command.Connection;
executeOnly.CommandType = CommandType.Text;
executeOnly.CommandText = "SET NOEXEC ON;" + sqlCommand;
executeOnly.Connection.Open();
executeOnly.ExecuteNonQuery();
//set more properties of command.
command.Execute();
由于莫名其妙的原因,“SET PARSEONLY ON
”只在查询分析器中有效。我无法在 ADO.NET 连接上设置它。这也很好,因为PARSEONLY
似乎只捕获语法错误,这不是常见的错误。 SET NOEXEC ON
将捕获更多种类的错误,例如引用缺失表或列或存储过程中缺失参数的视图。
【问题讨论】:
我假设它是executeOnly.CommandText = "SET NOEXEC ON; " + sqlCommand;
:3
【参考方案1】:
我认为您要查找的命令是SET NOEXEC ON
。如果你为你的连接设置了这个,查询将被解析但不会被执行。另一种选择是SET PARSEONLY ON
,但老实说,我不确定两者之间的真正区别是什么。
【讨论】:
+1, SET NOEXEC (Transact-SQL) 根据我的回答从 cmets 开始,我认为 SQL 2K8 中的 SET NOEXEC ON 可能存在错误 - 也已被其他人复制。查看我提出的 MS Connect 错误:connect.microsoft.com/SQLServer/feedback/details/569263/… PARSEONLY 只解析,NOEXEC 不执行但解析并编译。即,在丢失的表等上抛出错误。【参考方案2】:+1 埃里克的回答。但我发现SET FMTONLY ON
也很有用,因为SET NOEXEC ON
似乎不会抛出所有错误。
例如
SELECT * FROM ATableThatDoesNotExist
使用SET NOEXEC ON
运行它表示成功,尽管数据库中不存在该表。使用SET FMTONLY ON
运行它会抛出“无效的对象名称”错误。
SET FMTONLY ON 还返回有关将返回的结果集的元数据,这非常方便
【讨论】:
使用SET NOEXEC ON
和SELECT * FROM ATableThatDoesNotExist
时出现错误
@KM @Ada 抱歉,我的SET NOEXEC ON
和SELECT
之间没有重要的“GO”
我没有使用 GO,我只是运行 SET NOEXEC ON
并收到 Command(s) completed successfully.
消息,然后运行查询,然后产生了错误。如果您运行SET NOEXEC ON;SELECT...
,则不会出现错误。通过在 SRET 和 SELECT 之间对接 GO
会给出错误
@KM - 啊哈。对我来说,在 SQL Server 2008 RTM 上我从来没有得到错误。但是,当我在 SQL Server 2005 上尝试时,它的行为与您所说的一样,当您有 GO 语句时。您在哪里尝试 2005?行为发生了变化似乎很奇怪
+1 for SET FMTONLY ON 还返回有关结果集的元数据。这对于在不执行实际 SQL 语句的情况下进行故障排除非常有用,特别是对于 QA 环境中的开发人员 :)【参考方案3】:
SQL Server 2012 可以使用以下系统过程和函数解析您的语法、过程和表:
sp_describe_first_result_set (Transact-SQL) sp_describe_undeclared_parameters (Transact-SQL) sys.dm_exec_describe_first_result_set (Transact-SQL) sys.dm_exec_describe_first_result_set_for_object (Transact-SQL)They are supposedly replacing "SET FMTONLY".
我已经对它们进行了测试,它们比“SET NOEXEC ON”和“SET PARSEONLY ON”好很多
示例:
不会抛出错误:
sp_describe_undeclared_parameters
@tsql = N'SELECT object_id, name, type_desc FROM sys.indexes;'
会正确抛出错误(“SET NOEXEC”和“SET PARSEONLY”在这种情况下不会抛出错误):
sp_describe_undeclared_parameters
@tsql = N'SELECT object_id, name, type_desc FROM sys.indexes;SELECT object_id, name, type_desc FROM sys.NOTaTABLE;'
【讨论】:
【参考方案4】:使用以下查询
SET PARSEONLY ON
--Your query here
SET PARSEONLY OFF
【讨论】:
与 set statistics time, io on 不同,您的示例仍然执行查询:SET PARSEONLY ON;选择“确定”;设置 PARSEONLY 关闭;我们必须在关闭它之前添加 go 吗?【参考方案5】:SET PARSEONLY:检查每个 Transact-SQL 语句的语法并返回任何错误消息,而不编译或执行语句。
【讨论】:
这是 SSMS 在您按下绿色复选框时所做的事情。您可以在 SQL Profiler 中轻松看到它发生的情况。【参考方案6】:实际上,这取决于测试的目的。
最可靠的方法是在每次测试后使用回滚,前提是您的语句适合这样做(重量不会太重而无法实现)。
我过去曾这样做过,并且很高兴收到运行时问题的通知,而我不会以其他任何方式发现这些问题。
【讨论】:
+1 - 我同意。真正执行语句并在之后进行回滚将是最可靠的测试方式。 +1:SET NOEXEC ON
仅检查查询是否有效。查询可以是有效的,但不能返回正确的结果。【参考方案7】:
VSTSDBPro 有一个可以通过编程方式访问的查询解析器:http://blogs.msdn.com/b/gertd/archive/2008/08/21/getting-to-the-crown-jewels.aspx
【讨论】:
以上是关于如何以编程方式检查(解析)SQL 语句的有效性?的主要内容,如果未能解决你的问题,请参考以下文章
如何以编程方式检查 .NET 中的有效删除(修改)或写入权限?
在 C# 中以编程方式检查字符串是不是包含有效的 C# 代码
如何以编程方式检查系统上是不是安装了 SQL Server Management Studio?
如何以编程方式为 Django 中的给定模型生成 CREATE TABLE SQL 语句?