我正在尝试将文件夹中的200,000个文档插入到varbinary
列的SQL Server数据库中。插入80,000个文档后,我收到超时到期消息。平均文件大小约为250kb,最大文件大小为50MB。我在数据库所在的服务器上运行此c#程序。
请建议。
错误:
操作完成之前经过的超时时间或服务器没有响应。
代码:
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();
}
答案 0 :(得分:0)
为此,我建议使用SQLBulkCopy方法,因为它应该能够更轻松地处理数据插入。此外,正如其他人指出的那样,您可能希望增加命令的超时条件。
答案 1 :(得分:0)
虽然我同意这可能最适合某种批量副本,如果你必须在c#程序中这样做,你唯一的选择可能是增加超时值。您可以在通过SqlCommand
创建cmd.CommandTimeout = <new timeout>;
对象后执行此操作。属性CommandTimeout
是一个整数,表示超时的秒数,如果您不希望它超时,则为零。 / p>
有关详细信息,请参阅MSDN docs
答案 2 :(得分:0)
您应该能够在应用程序代码中直接在该对象上设置事务的超时,这样您就不会更改sql server设置。
其次,您也可以在应用程序中构建批次。你说你可以在超时之前获得80k文档,将批量大小设置为50k,处理它们,提交它们,抓住下一批。让您的应用程序管理批处理还允许您捕获sql错误,例如超时,然后动态调整批处理大小并重试,而不会崩溃。这是首先编写应用程序的全部原因,否则您可以在管理工作室中使用向导并手动插入文件。
我强烈建议您使用其他选项进行批处理。
@Shubham Pandey还提供了一个很好的链接到SQL批量复制信息,它也有更多信息的链接。你绝对应该尝试批量复制类,看看你是否可以获得额外的收益。