如何以编程方式检查(解析)TSQL语句的有效性?

Mat*_*tin 50 .net c# t-sql sql-server ado.net

我正在努力使我的集成​​测试更具幂等性.一个想法是在每次测试后执行回滚,另一个想法是一些程序如何以编程方式解析文本,类似于查询分析器或SSMS中的绿色复选框.

如何在不使用ADO.NET运行SQL Server的情况下解析命令?

更新: 这是最终按预期工作的:

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();
Run Code Online (Sandbox Code Playgroud)

出于莫名其妙的原因," SET PARSEONLY ON"仅在查询分析器中有效.我无法在ADO.NET连接上设置它.它也是如此,因为PARSEONLY似乎只捕获语法错误,这不是一个常见的错误. SET NOEXEC ON将捕获更多种类的错误,例如引用缺少的表或列的视图或存储过程中缺少的参数.

Eri*_*lje 38

我认为你正在寻找的命令是SET NOEXEC ON.如果为连接设置此项,则将解析查询但不会执行.另一个选择是SET PARSEONLY ON,但老实说我不确定两者之间的区别是什么.

  • 根据我的回答中的评论,我认为在SQL 2K8中可能存在SET NOEXEC ON的错误 - 也被其他人复制了.退房MS连接错误,我提出:https://connect.microsoft.com/SQLServer/feedback/details/569263/set-noexec-on-does-not-flag-up-invalid-object-name-errors (4认同)

Ada*_*Dev 22

给Eric的答案+1.但我发现SET FMTONLY ON它也很有用,因为SET NOEXEC ON它似乎没有引起所有错误.

例如

SELECT * FROM ATableThatDoesNotExist
Run Code Online (Sandbox Code Playgroud)

SET NOEXEC ON尽管数据库中没有表,但运行它表示它是成功的.SET FMTONLY ON相反,运行它会抛出"无效的对象名称"错误.

SET FMTONLY ON还返回有关将返回的结果集的元数据,这可以非常方便


Jar*_*eth 8

SQL Server 2012可以使用以下系统过程和函数解析语法,过程和表:

他们应该取代"SET FMTONLY".

我测试了它们,它们比"SET NOEXEC ON"和"SET PARSEONLY ON"工作得更好

例子:

不会抛出错误:

sp_describe_undeclared_parameters
    @tsql = N'SELECT object_id, name, type_desc FROM sys.indexes;'
Run Code Online (Sandbox Code Playgroud)

将正确抛出错误("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;'
Run Code Online (Sandbox Code Playgroud)


Ral*_*ine 7

使用以下查询

SET PARSEONLY ON
--Your query here
SET PARSEONLY OFF
Run Code Online (Sandbox Code Playgroud)


Pra*_*ana 6

SET PARSEONLY:检查每个Transact-SQL语句的语法并没有编译或执行的语句返回任何错误消息.


Mar*_*ith 6

真的,这取决于测试的目的.

最可靠的方法是在每次测试后使用回滚,如果你的陈述适合它(不是太重,不能使它可行).

我过去已经这样做了,并且很高兴收到运行时问题的通知,我不会以任何其他方式捕获.