批量将多个文档插入SQL Server 2016

时间:2018-02-22 14:23:47

标签: c# sql-server tsql sql-server-2016

我正在尝试从该文件夹批量插入多个文档(超过50,000个)。我有这个程序,但它很耗时。请建议任何其他方式。

string[] files = Directory.GetFiles("C:\\TEST\\", "*.*", SearchOption.AllDirectories);
using (SqlConnection con= new SqlConnection (conString))
{
    con.Open();
     foreach (string docPath in files)
            {
                   byte[] file;    
                    using (var stream = new FileStream(docPath, FileMode.Open, FileAccess.Read))
                    {
                        using (var reader1 = new BinaryReader(stream))
                        {
                            file = reader1.ReadBytes((int)stream.Length);
                        }
                    }

        string insertSQLString = "INSERT INTO dbo.Test(content, path) VALUES(@File, @path)";
        using (SqlCommand cmd = new SqlCommand (insertSQLString, con))
        {
            cmd.Parameters.Add("@File", SqlDbType.VarBinary, file.Length).Value = file;                             
            cmd.Parameters.Add("@path", SqlDbType.Text).Value = docPath;
            cmd.ExecuteNonQuery();
        }
    }
}

2 个答案:

答案 0 :(得分:1)

您可以使用SqlBulkCopy中的System.Data.SqlClient类。插入大量数据时非常有效。

在这里,您可以找到一个示例:http://codinghelmet.com/?path=howto/bulk-insert

答案 1 :(得分:1)

以下是一些优化。在发送到SQL之前,无需将文件内容复制到字节数组。您可以直接传递Stream。见SqlClient Streaming Support。如果文件很小,你会想要在提交中一起批量处理。此外,每次都不必重新创建SqlCommand。

        static void Run()
        { 
            string[] files = Directory.GetFiles("C:\\TEST\\", "*.*", SearchOption.AllDirectories);
            using (SqlConnection con = new SqlConnection("server=localhost;database=testdb;integrated security=true"))
            {
                con.Open();
                string insertSQLString = "INSERT INTO dbo.Test(content, path) VALUES(@File, @path)";
                SqlCommand cmd = new SqlCommand(insertSQLString, 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)
                {
                    fn += 1;
                    using (var stream = new FileStream(docPath, FileMode.Open, FileAccess.Read))
                    {
                        pFile.Value = stream;
                        pPath.Value = docPath;
                        cmd.Transaction = tran;
                        cmd.ExecuteNonQuery();
                        if (fn%10==0)
                        {
                            tran.Commit();
                            tran = con.BeginTransaction();
                            Console.Write("|");
                        }
                        Console.Write(".");
                    }
                }
                tran.Commit();
            }
        }

另一种方法是创建File Table然后只复制文件。