我有一个非常大的sql文件,我想分成批处理执行。 我想确保我以与SSMS和SQLCMD相同的方式解析它。
Microsoft有一个很棒的混合模式程序集,名为Microsoft.SqlServer.BatchParser,其中有一个名为Parser的类,它可以像它一样接缝。
它希望在调用Parse()之前将IBatchSource的实现作为SetBatchSource的参数。
我在哪里可以找到IBatchSource的实现,以及有关如何使用此功能的更多信息?
答案 0 :(得分:13)
我在GAC中找到了程序集Microsoft.SqlServer.BatchParser以及它的朋友Microsoft.SqlServer.BatchParserClient,其中包含IBatchSource接口的实现。
namespace Microsoft.SqlServer.Management.Common
{
internal class BatchSourceFile : IBatchSource
internal class BatchSourceString : IBatchSource
}
然后发生了以下对话。
汇编:您好!我的名字是 的 Microsoft.SqlServer.Management.Common.ExecuteBatch 即可。你想要StringCollection GetStatements(string sqlCommand)吗?
我:是的,我会,BatchParserClient汇编。谢谢你的询问!
可重复说明(请在家中试试!)
<强> Program.cs的强>
using System;
using System.Collections.Specialized;
using System.IO;
using System.Text;
using Microsoft.SqlServer.Management.Common;
namespace ScriptParser
{
class Program
{
static void Main(string[] args)
{
ExecuteBatch batcher = new ExecuteBatch();
string text = File.ReadAllText(@"Path_To_My_Long_Sql_File.sql");
StringCollection statements = batcher.GetStatements(text);
foreach (string statement in statements)
{
Console.WriteLine(statement);
}
}
}
}
<强> App.Config中强>
<?xml version="1.0"?>
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
</startup>
</configuration>
另一种选择是使用本答案中描述的ScriptDom:https://stackoverflow.com/a/32529415/26877。
using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.SqlServer.TransactSql.ScriptDom;
namespace ScriptDomDemo
{
class Program
{
static void Main(string[] args)
{
TSql120Parser parser = new TSql120Parser(false);
IList<ParseError> errors;
using (StringReader sr = new StringReader(@"create table t1 (c1 int primary key)
GO
create table t2 (c1 int primary key)"))
{
TSqlFragment fragment = parser.Parse(sr, out errors);
IEnumerable<string> batches = GetBatches(fragment);
foreach (var batch in batches)
{
Console.WriteLine(batch);
}
}
}
private static IEnumerable<string> GetBatches(TSqlFragment fragment)
{
Sql120ScriptGenerator sg = new Sql120ScriptGenerator();
TSqlScript script = fragment as TSqlScript;
if (script != null)
{
foreach (var batch in script.Batches)
{
yield return ScriptFragment(sg, batch);
}
}
else
{
// TSqlFragment is a TSqlBatch or a TSqlStatement
yield return ScriptFragment(sg, fragment);
}
}
private static string ScriptFragment(SqlScriptGenerator sg, TSqlFragment fragment)
{
string resultString;
sg.GenerateScript(fragment, out resultString);
return resultString;
}
}
}