从C#中的字符串检测SQL查询

时间:2017-10-15 14:33:32

标签: c# sql-server

我已经搜索了很多关于我的问题的内容,甚至在SO中查看了很多QAs,但是找不到我想要的内容,无论如何,如果这是一个重复的问题,那就很抱歉。 这是我的情景: 我在C#中有一个字符串,它应该用作SQL Server查询。但是这个字符串可以是任何东西,从简单的(从B中选择A)到复杂的SP(可能包含多个命令)。如何显式检测此字符串中的每个查询? 例如,假设我们有以下字符串:

select columnA from tblB
delete tblD where ID='100'
insert into tblF (name) values ('test')

上面的文字显然由3个不同的查询组成,每个查询都应该以自己特定的方式执行,即第一个(select)需要ExecuteReader,我应该显示结果表,而其他查询需要ExecuteNonQuery。所以内部我应该运行3个SQL查询,但问题是我如何区分这3个查询?我不能像在SQL中那样用'\ n'简单地拆分字符串,可以用多行来编写查询。检测不同查询的最佳/正确方法是什么? (SQL Server Management Studio是我正在寻找的完美示例) 我应该使用SQL Parsers吗?如果是这样,我应该寻找什么?我也见过很多解析器,但我真的很困惑,因为我不知道我应该从他们那里得到什么。

我尽力描述这个问题! 提前致谢

1 个答案:

答案 0 :(得分:6)

你可以添加Microsoft.SqlServer.TransactSql.ScriptDom的引用然后这是非常直接的(至少对于快乐的路径)

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

namespace MyApp
{
    class Program
    {
        static void Main(string[] args)
        {

            var sql = @"
SELECT columnA
FROM   tblB
WHERE  ColumnB = 1

DELETE tblD
WHERE  ID = '100'

INSERT INTO tblF
            (NAME)
VALUES      ('test'),
            ('foo'),
            ('bar') 
";

            var parser = new TSql100Parser(true); //Or TSql120Parser or whatever
            IList<ParseError> errors = new List<ParseError>();

            TSqlScript script = (TSqlScript)parser.Parse(new StringReader(sql), out errors);

            //TODO: Don't ignore errors
            foreach (var batch in script.Batches)
            {
                foreach (var st in batch.Statements)
                {
                    Console.WriteLine(st.GetType().Name);
                    Console.WriteLine(sql.Substring(st.StartOffset, st.FragmentLength));
                    Console.WriteLine();
                }
            }
        }
    }
}

返回

Batch Documentation