简体   繁体   English

SQL Server插入超时已过期

[英]Timeout expired with SQL Server insert

I am trying to insert 200,000 documents from a folder into the SQL Server database into a varbinary column. 我试图将200,000个文档从一个文件夹插入SQL Server数据库的varbinary列中。 I get a timeout expiration message after inserting 80,000 documents. 插入80,000个文档后,我收到超时消息。 Average file size is about 250kb and max file size is 50MB. 平均文件大小约为250kb,最大文件大小为50MB。 I am running this c# program on the server where the database is located. 我在数据库所在的服务器上运行此c#程序。

Please suggest. 请提出建议。

The error: 错误:

The timeout period elapsed prior to completion of the operation or the server is not responding. 在操作完成之前超时或服务器没有响应。

The code: 编码:

string spath = @"c:\documents";
string[] files = Directory.GetFiles(spath, "*.*", SearchOption.AllDirectories);
Console.Write("Files Count:" + files.Length);

using (SqlConnection con = new SqlConnection(connectionString))
{
  con.Open();
  string insertSQL = "INSERT INTO table_Temp(doc_content, doc_path) values(@File, @path)";

  SqlCommand cmd = new SqlCommand(insertSQL, con);
  var pFile = cmd.Parameters.Add("@File", SqlDbType.VarBinary, -1);
  var pPath = cmd.Parameters.Add("@path", SqlDbType.Text);

  var tran = con.BeginTransaction();
  var fn = 0;

  foreach (string docPath in files)
  {
    string newPath = docPath.Remove(0, spath.Length);

    string archive = new DirectoryInfo(docPath).Parent.Name;
    fn += 1;

    using (var stream = new FileStream(docPath, FileMode.Open, FileAccess.Read))
    {
      pFile.Value = stream;
      pPath.Value = newPath;

      cmd.Transaction = tran;
      cmd.ExecuteNonQuery();

      if (fn % 10 == 0)
      {
        tran.Commit();
        tran = con.BeginTransaction();
        Console.Write("|");
      }

      Console.Write(".");
    }
  }

  tran.Commit();
}

For this, I would suggest using SQLBulkCopy methods, since it should be able to handle data insertion much more easily. 为此,我建议使用SQLBulkCopy方法,因为它应该能够更轻松地处理数据插入。 Further, as others have pointed out, you might want to increase the timeout condition for your command. 此外,正如其他人指出的那样,您可能希望增加命令的超时条件。

While I would agree this may be best for a bulk copy of some sort, if you must do this in the c# program, your only option is probably to increase the timeout value. 虽然我同意这对于某种形式的批量复制可能是最好的,但是如果必须在c#程序中执行此操作,则唯一的选择可能是增加超时值。 You can do this after your SqlCommand object has been created via cmd.CommandTimeout = <new timeout>; 您可以在通过cmd.CommandTimeout = <new timeout>;创建SqlCommand对象之后执行此操作cmd.CommandTimeout = <new timeout>; The property CommandTimeout is an integer representing the number seconds for the timeout, or zero if you never want it to timeout. CommandTimeout属性是代表超时秒数的整数,如果您从不希望超时,则为零。

See the MSDN docs for details 有关详细信息,请参见MSDN文档

You should be able to set the timeout for the transaction directly on that object in your application code, this way you are not changing sql server settings. 您应该能够在应用程序代码中直接在该对象上设置事务超时,这样就不会更改sql server设置。

Secondly, you can build batches in your application also. 其次,您也可以在应用程序中构建批处理。 You say you can get 80k docs before a timeout, set your batch size at 50k, process them, commit them, grab the next batch. 您说您可以在超时前获取80k文档,将批量大小设置为50k,进行处理,提交,然后获取下一批。 Having your application manage batching also allows you to catch sql errors, such as timeout, and then dynamically adjust the batch size and retry without ever crashing. 让应用程序管理批处理还可以使您捕获sql错误(例如超时),然后动态调整批处理大小并重试而不会崩溃。 This is the entire reason for writing your application in the first place, other wise you could just use the wizard in management studio and manually insert your files. 这是首先编写应用程序的全部原因,否则,您可以只使用Management Studio中的向导并手动插入文件。

I highly recommend batching over other options. 我强烈建议在其他选项上进行批处理。

@Shubham Pandey also provides a great link to SQL bulk copy info, which also has links to more info. @Shubham Pandey还提供了指向SQL批量复制信息的出色链接,该链接还提供了指向更多信息的链接。 You should definitely experiment with the bulk copy class and see if you can get additional gains with it as well. 您绝对应该尝试批量复制类,看看是否还可以从中获得更多收益。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM