如何用T-SQL判断SQL语法是否正确

简介:

前几天在论坛看到有个帖子提问是否可以在应用程序中检查SQL Server的语法,当时自己也不清楚。

今天在看SQL Server Set设置,发现有两个选项可以实现这个功能:

1.SET PARSEONLY选项(类似于SSMS的Cntrl+F5)

这个选项检查每个 Transact-SQL 语句的语法并返回任何错误消息,但不编译和执行语句。

下面我们创建一个存储过程用来检查输入的语句是否正确:

create procedure IsValidSQL(@sqlvarchar(max))as

begin

begin try

set @sql='set parseonly on;'+@sql;

exec(@sql);

end try

begin catch

return(1);

end catch;

return(0);

end;-- IsValidSQL

--这条语句语法没有问题,返回值为0

declare @retvalint;

exec@retval=IsValidSQL'select back from t ';

select@retval

--因为from语句没有了,所以语法错误,返回值为1

declare @retvalint;

exec@retval=IsValidSQL'select back f t ';

select@retval

因为SET PARSEONLY只是验证语法不会生产执行计划,可以通过下面的语句验证:

SET PARSEONLY ON

go

select*from[HumanResources].[Department]

go

SET PARSEONLY off

--可以确定执行计划没有生产

SELECT'1'AS RoundNum,usecounts, cacheobjtype,objtype,text

FROM sys.dm_exec_cached_plans

CROSS APPLYsys.dm_exec_sql_text(plan_handle)

WHERE usecounts> 0 AND

text like'%HumanResources%'

AND text NOT LIKE '%Check%'

ORDER BY usecounts DESC;

GO

注意:SET PARSEONLY 的设置是在分析时设置,而不是在执行或运行时设置。

在存储过程或触发器中不要使用 PARSEONLY。另外这个检查虽然可以证明语法没有问题,但是不会检查到对象不存在或者逻辑上的问题。

2. SET NOEXEC : 编译每个查询,但不执行该查询。

 SET NOEXEC  ON 时,SQL Server 将编译每一批处理 Transact-SQL 语句但并不执行它们。 SET NOEXEC 设置为 OFF 时,所有批处理将在编译后执行。

以下示例在有效查询、包含无效对象名称的查询以及包含不正确语法的查询中使用 NOEXEC

USEAdventureWorks2012;

GO

PRINT'Valid query';

GO

-- SETNOEXEC to ON.

SET NOEXEC ON;

GO

-- Innerjoin.

SELECTe.BusinessEntityID,e.JobTitle,v.Name

FROM HumanResources.EmployeeAS e

INNER JOINPurchasing.PurchaseOrderHeaderAS poh

ON e.BusinessEntityID=poh.EmployeeID

INNER JOIN Purchasing.VendorAS v

ON poh.VendorID=v.BusinessEntityID;

GO

-- SETNOEXEC to OFF.

SET NOEXEC OFF;

GO

PRINT'Invalid object name';

GO

-- SETNOEXEC to ON.

SET NOEXEC ON;

GO

--Function name uses is a reserved keyword.

USE AdventureWorks2012;

GO

CREATE FUNCTION dbo.Values(@BusinessEntityIDint)

RETURNS TABLE

AS

RETURN (SELECTPurchaseOrderID, TotalDue

FROM dbo.PurchaseOrderHeader

WHERE VendorID=@BusinessEntityID);

 

-- SETNOEXEC to OFF.

SET NOEXEC OFF;

GO

PRINT'Invalid syntax';

GO

-- SETNOEXEC to ON.

SET NOEXEC ON;

GO

--Built-in function incorrectly invoked.

SELECT*

FROMfn_helpcollations;

-- ResetSET NOEXEC to OFF.

SET NOEXEC OFF;

GO

这个选项会编译每个查询,比上面的选项检查的要多。我们可以用Try Catch选项判断,针对错误判断写出来的语句是否有问题。

 

SET NOEXEC

SET PARSEONLY

本文转自 lzf328 51CTO博客,原文链接:

http://blog.51cto.com/lzf328/1256813
相关文章
|
6月前
|
SQL Oracle 关系型数据库
Oracle数据库创建表空间和索引的SQL语法示例
以上SQL语法提供了一种标准方式去组织Oracle数据库内部结构,并且通过合理使用可以显著改善查询速度及整体性能。需要注意,在实际应用过程当中应该根据具体业务需求、系统资源状况以及预期目标去合理规划并调整参数设置以达到最佳效果。
432 8
|
SQL 存储 关系型数据库
【MySQL基础篇】全面学习总结SQL语法、DataGrip安装教程
本文详细介绍了MySQL中的SQL语法,包括数据定义(DDL)、数据操作(DML)、数据查询(DQL)和数据控制(DCL)四个主要部分。内容涵盖了创建、修改和删除数据库、表以及表字段的操作,以及通过图形化工具DataGrip进行数据库管理和查询。此外,还讲解了数据的增、删、改、查操作,以及查询语句的条件、聚合函数、分组、排序和分页等知识点。
1247 56
【MySQL基础篇】全面学习总结SQL语法、DataGrip安装教程
|
SQL 关系型数据库 MySQL
MySQL数据库基础第一篇(SQL通用语法与分类)
MySQL数据库基础第一篇(SQL通用语法与分类)
|
SQL PHP
thinkphp之进阶sql语法,持续更新
thinkphp之进阶sql语法,持续更新
196 0
|
SQL 存储 关系型数据库
SQL `CREATE DATABASE` 语法
【11月更文挑战第10天】
474 3
|
SQL 关系型数据库 数据库
sql语法
【10月更文挑战第26天】sql语法
245 5
|
SQL 数据库
SQL数据库基础语法入门
[link](http://www.vvo.net.cn/post/082935.html)
|
SQL 关系型数据库 数据库
sql语法
【7月更文挑战第30天】sql语法
241 12
|
SQL 关系型数据库 MySQL
INSERT INTO t_a.tableName SELECT * FROM t_b.tableName 如何通过定义一个list对象,包含多个tableName,循环执行前面的sql,用MySQL的语法写
【8月更文挑战第7天】INSERT INTO t_a.tableName SELECT * FROM t_b.tableName 如何通过定义一个list对象,包含多个tableName,循环执行前面的sql,用MySQL的语法写
222 5
|
SQL 存储 关系型数据库
mysql SQL必知语法
本文详细介绍了MySQLSQL的基本语法,包括SELECT、FROM、WHERE、GROUPBY、HAVING、ORDERBY等关键字的使用,以及数据库操作如创建、删除表,数据类型,插入、查询、过滤、排序、连接和汇总数据的方法。通过学习这些内容,读者将能更好地管理和操
372 0