Tôi đã tìm thấy tập hợp Microsoft.SqlServer.BatchParser trong GAC cùng với người bạn đó là Microsoft.SqlServer.BatchParserClient có chứa triển khai giao diện IBatchSource.
namespace Microsoft.SqlServer.Management.Common
{
internal class BatchSourceFile : IBatchSource
internal class BatchSourceString : IBatchSource
}
Cuộc hội thoại sau đó xảy ra.
Lắp ráp: Xin chào! Tên tôi là Microsoft.SqlServer.Management.Common.ExecuteBatch. Bạn có muốn StringCollection GetStatements (chuỗi sqlCommand) không?
Tôi: Có, tôi sẽ, lắp ráp BatchParserClient. Cam ơn vi đa hỏi!
Hướng dẫn lặp (Đừng thử loại này ở nhà!)
- Install Microsoft SQL Server 2008 R2 Shared Management Objects
- Sao chép Microsoft.SqlServer.BatchParser.dll và Microsoft.SqlServer.BatchParserClient.dll từ GAC đến một trong thư mục của bạn.
- Reference Microsoft.SqlServer.BatchParser & Microsoft.SqlServer.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>
Một lựa chọn khác là sử dụng ScriptDom như được mô tả trong câu trả lời này: 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;
}
}
}
Xin lỗi, nhưng 'Tệp.ReadAllText' sẽ vẫn đọc toàn bộ tệp vào bộ nhớ trước. Vì vậy, với các tập tin lớn (có thể không hợp lý lớn, nhưng vẫn còn), bạn có vấn đề. Về cơ bản, một giao diện "streaming" sẽ được yêu cầu. Như tôi đã lưu ý [ở đây] (http://stackoverflow.com/a/12154400/21567), 'SQLCMD.EXE' có thể làm điều đó, và có lẽ cũng sử dụng' IBatchSource', mặc dù việc thực hiện tự nhiên chứ không phải "wrapper" được quản lý. Câu hỏi vẫn còn là: làm thế nào để tách văn bản đầu vào thành các khối để BatchParser có thể hiểu được nó. (+1 mặc dù vẫn còn, cho một đóng góp tốt) –
@ Christian.K tìm thấy câu trả lời https: // stackoverflow.com/a/32529415/26877 có thể là một tùy chọn để phân tích cú pháp các lô của bạn bằng ScriptDOM. – JJS