【问题标题】:Read a large SQL script file in c#在 C# 中读取一个大型 SQL 脚本文件
【发布时间】:2015-12-08 07:04:45
【问题描述】:

我正在尝试阅读大型脚本,到目前为止,我尝试了两种选择:

选项 1:

由于内存空间不足的问题,我们无法在 SQL 管理工作室中打开大型脚本文件,所以最初我使用sqlcmd 在远程主机上执行 160 mb 的 SQL 脚本文件,55 分钟后影响了一些行出现此错误,TCP Provider: An existing connection was forcibly closed by the remote host. , communication link failure.

选项 2:

现在我正在尝试使用 this 示例,文件大小为 160 MB,包含许多插入语句,但 Visual Studio 崩溃

代码:

public ActionResult Index()
{
   string scriptDirectory = "e:\\";
   string sqlConnectionString = "Integrated Security=SSPI;" +
   "Persist Security Info=True;Initial Catalog=TestDB;Data Source=localhost\\SQLEXPRESS";
   DirectoryInfo di = new DirectoryInfo(scriptDirectory);
   FileInfo[] rgFiles = di.GetFiles("*.sql");
   foreach (FileInfo fi in rgFiles)
   {
        FileInfo fileInfo = new FileInfo(fi.FullName);
        string script = fileInfo.OpenText().ReadToEnd(); // here visual studio crashes
        SqlConnection connection = new SqlConnection(sqlConnectionString);
        Server server = new Server(new ServerConnection(connection));
        server.ConnectionContext.ExecuteNonQuery(script);
   }

       return View();
}

屏幕截图:

【问题讨论】:

  • 您的脚本是否包含GO 分隔符?还是只有INSERT... 行?
  • 为什么 Visual Studio 会读取文件?目前尚不清楚为什么要在 Visual Studio 可执行文件中执行代码。 (另外,请格式化您的代码以使其更具可读性。)
  • @Dennis,是的,它包含 GO 分隔符,因为脚本文件是使用 Sql management studio 中的生成脚本向导生成的。
  • 如果只有INSERTs和GOs,那么手动解析这个文件比较容易。只需逐行读取文件,跳过GO 语句,并在每个SqlCommand 中执行一个INSERT 语句。
  • @Jon Skeet,我已经进行了更改,谢谢。

标签: c# sql-server


【解决方案1】:

我建议逐行执行插入语句,可选地包含在事务中:

public ActionResult Index()
{
    string scriptDirectory = "e:\\";
    string sqlConnectionString = "Integrated Security=SSPI;" +
        "Persist Security Info=True;Initial Catalog=TestDB;Data Source=localhost\\SQLEXPRESS";

    using(var connection = new SqlConnection(sqlConnectionString))
    {
        var transaction = connection.BeginTransaction();
        using(var command = connection.CreateCommand())
        {
            ProcessFiles(command, scriptDirectory);
        }
        transaction.Commit();
    }
    return View();
}

private void ProcessFiles(SqlCommand command, string scriptDirectory)
{
    foreach(var file in Directory.GetFiles(scriptDirectory,"*.sql"))
    {
        using(var reader = new StreamReader(file))
        {
            while(!reader.EndOfStream)
            {
                var line = reader.ReadLine();
                if(!line.StartsWith("GO"))
                {
                    command.CommandText = line;
                    command.ExecuteNonQuery();
                }
            }
        }
    }        
}

请记住,这会给数据库的日志文件带来一些压力。

【讨论】:

    猜你喜欢
    • 2021-07-20
    • 2021-12-05
    • 2011-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多