用于验证SQL脚本的代码

时间:2010-07-18 15:05:30

标签: c# .net sql sql-server

如何在使用.net 2.0和c#执行sql脚本之前验证它们?

如果sql无效,我想返回错误行。

4 个答案:

答案 0 :(得分:42)

答案 1 :(得分:16)

SSMS有办法做到这一点。

如果您使用SQL事件探查器,您将看到它执行SET PARSEONLY ON,然后执行SQL,然后SET PARSEONLY OFF,并且在不编译或执行查询的情况下会出现任何错误。

SET PARSEONLY ON;
SELECT * FROM Table; --Query To Parse
SET PARSEONLY OFF; 

PARSEONLY

我从未尝试过使用c#,但我认为没有理由说它不起作用,毕竟它适用于SSMS。

正如Martin Smith在评论中指出的那样,您可以使用SET NOEXEC ON

MSDN对以下两个命令说了以下内容。

  

当SET NOEXEC为ON时,SQL Server   编译每批Transact-SQL   语句但不执行它们。   当SET NOEXEC为OFF时,所有批次   在编译后执行。

     

当SET PARSEONLY为ON时,SQL Server仅解析该语句。什么时候   SET PARSEONLY为OFF,SQL Server   编译并执行声明。

这表明NOEXEC也将编译PARSEONLY不会的查询。因此NOEXEC可能会发现PARSEONLY没有的错误。用法是一样的。

SET NOEXEC ON;
SELECT * FROM Table; --Query To Parse
SET NOEXEC OFF; 

NOEXEC

答案 2 :(得分:5)

我知道问题是关于.NET 2.0的,但对某些人来说可能很有趣。在最新版本的Microsoft SQL Server中,查询验证略有变化。 名称空间为Microsoft.SqlServer.TransactSql.ScriptDom,而不是Microsoft.Data.Schema.ScriptDom

在哪里可以找到这个库?

图书馆的路径是%programfiles(x86)%\Microsoft SQL Server\120\SDK\Assemblies 如果找不到此库并安装了Microsoft SQL Server,请尝试从120更改为110100并使用相应的解析器(TSql110Parser或{{1}分别)。

如何使用?

我有两个扩展:第一个扩展检查输入字符串是否是有效的SQL查询,第二个扩展可用于从解析中获取错误。

TSql100Parser

另外,我检查输入的SQL查询不是null或为空,因为解析器认为空字符串是完全有效的(我不判断它)。

如何测试?

有三个NUnit测试,显示如何使用此扩展。

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

public static class SqlStringExtensions
{
    public static bool IsValidSql(this string str)
    {
        return !str.ValidateSql().Any();
    }

    public static IEnumerable<string> ValidateSql(this string str)
    {
        if (string.IsNullOrWhiteSpace(str))
        {
            return new[] { "SQL query should be non empty." };
        }
        var parser = new TSql120Parser(false);
        IList<ParseError> errors;
        using (var reader = new StringReader(str))
        {
            parser.Parse(reader, out errors);
        }
        return errors.Select(err => err.Message);
    }
}

答案 3 :(得分:0)

'有效'SQL是什么意思?语法或结果?

验证语法的唯一可靠方法是在SQL Server中执行SQL。您是否考虑在事务中运行SQL,然后在最后执行回滚?

Begin Transaction

--execute your code between the 'Begin Transaction' and the 'rollback' keywords.
...

--example
Insert into mytable(ID)Values(2)

...

Rollback
回滚时

MSDN Documentation