简体   繁体   English

一次性在SQL Server 2008中插入1000条以上的记录

[英]Insert more than 1000 records in SQL Server 2008 in one go

I am creating a WPF application where clients can insert multiple records into a database. 我正在创建一个WPF应用程序,客户端可以在其中将多个记录插入数据库中。

Minimum limit of records to insert is 1000. 插入记录的最小限制为1000。

I used below code to insert the same in c#. 我使用下面的代码在c#中插入了相同的代码。

var response = SearchEngine.Search(objSearchRequest);

if (response.ResponseStatus == SearchResponse.SearchResponseStatus.Success)
{
    ImageClippingQueue objImageClippingQueue;

    if (response.SearchResults.Count > 0)
    {
       foreach (var item in response.SearchResults)
       {
          objImageClippingQueue = new ImageClippingQueue();
          objImageClippingQueue.ImageID = item.Value.ImageId;
          objImageClippingQueue.pubid = item.Value.PubId;

          new CommonMethods().InsertImageData(objImageClippingQueue);
       }

       UpdateClippingSearchKeyword(keywordId, response.TotalAvailableResults, (int)totalRecordsImported);
    }
}

This method InsertImageData inserts data into database. 此方法InsertImageData将数据插入数据库。

Is there any fastest way to go so that database hit should be one and not hitting again and again. 有没有什么最快的方法可以使数据库命中一次而不是一次又一次命中。

Thanks 谢谢

You can make use of the SqlBulkCopy class to insert the data. 您可以使用SqlBulkCopy类插入数据。 The following example was taken from http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlbulkcopy(v=vs.110).aspx 以下示例摘自http://msdn.microsoft.com/zh-cn/library/system.data.sqlclient.sqlbulkcopy(v=vs.110).aspx

            using (SqlBulkCopy bulkCopy =
                       new SqlBulkCopy(destinationConnection))
            {
                bulkCopy.DestinationTableName =
                    "dbo.BulkCopyDemoMatchingColumns";

                try
                {
                    // Write from the source to the destination.
                    bulkCopy.WriteToServer(reader);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
                finally
                {
                    // Close the SqlDataReader. The SqlBulkCopy 
                    // object is automatically closed at the end 
                    // of the using block.
                    reader.Close();
                }
            }

I've done something similar to the following: 我做了类似以下的事情:

public static void insert(List<myRecord> records)
{
    string sql = "insert into myTable (col1, col2) values ";

    int i = 0;
    foreach (record in records)
    {
        if (0 < i) sql += ",";

        sql += "(@col1_" + i + ",@col2_" + i + ")";
        ++i;
    }

    SqlConnection conn = new SqlConnection(myConnStr);
    SqlCommand cmd = new SqlCommand(sql, conn);

    i = 0;
    foreach (record in records)
    {
        cmd.Parameters.Add("@col1_" + i, System.Data.SqlDbType.Int).Value = record.Val1;
        cmd.Parameters.Add("@col2_" + i, System.Data.SqlDbType.Int).Value = record.Val2;
        ++i;
    }

    // and so on...
}

I've also had to limit it to only inserting say 500 records per insert but that is hidden from the client. 我还不得不将其限制为每个插入仅插入500条记录,但这对客户端是隐藏的。 Using a StringBuilder would also be an improvement. 使用StringBuilder也将有所改进。

I used a store procedure to complete this task. 我使用存储过程来完成此任务。

Link: http://programcall.com/11/dotnet/how-to-read-data-from-xml-string--and-insert-to-table-sql-server.aspx 链接: http//programcall.com/11/dotnet/how-to-read-data-from-xml-string--and-insert-to-table-sql-server.aspx

-- To import multiple records into database
Create PROCEDURE SP_Importimagedata (
 @xmlData XML 
)

AS
BEGIN

    INSERT INTO  [imagedata](
    ImageID,
    ImageClippingStatusID,
    [Priority],
    UserID,
    pubid,
    ClipTypeID
    )

    SELECT
    COALESCE([Table].[Column].value('ImageID[1]', 'int'),0) as 'ImageID',
    [Table].[Column].value('ImageClippingStatusID[1]', 'int') as 'ImageClippingStatusID',
    [Table].[Column].value(' Priority[1]', 'int') as 'Priority',
    [Table].[Column].value(' UserID[1]', 'int') as 'UserID',
    [Table].[Column].value(' pubid[1]', 'int') as 'pubid',
    [Table].[Column].value(' ClipTypeID[1]', 'int') as 'ClipTypeID'
    FROM @xmlData.nodes('/Images/Image') as [Table]([Column])
END


 var response = SearchEngine.Search(objSearchRequest);

            if (response.ResponseStatus == SearchResponse.SearchResponseStatus.Success)
            {
                if (response.SearchResults.Count > 0)
                {
                    sbCreateDataXml = new StringBuilder();
                    sbCreateDataXml.Append("<Images>");
                    foreach (var item in response.SearchResults)
                    {
                        sbCreateDataXml.Append("<Image>");
                        sbCreateDataXml.Append("<ImageID>" + item.Value.ImageId + "</ImageID>");
                        sbCreateDataXml.Append("<ImageClippingStatusID>" + imageClippingStatusID + "</ImageClippingStatusID>");
                        sbCreateDataXml.Append("<Priority>" + priority + "</Priority>");
                        sbCreateDataXml.Append("<UserID>" + userID + "</UserID>");
                        sbCreateDataXml.Append("<pubid>" + item.Value.PubId + "</pubid>");
                        sbCreateDataXml.Append("<ClipTypeID>" + clipTypeID + "</ClipTypeID>");
                        sbCreateDataXml.Append("</Image>");
                        counter++;
                    }
                    sbCreateDataXml.Append("</Images>");
                    new CommonMethods().InsertImageClippingQueue(sbCreateDataXml.ToString());
                    totalRecordsImported = (int)totalRecordsImported + counter;
                    UpdateClippingSearchKeyword(keywordId, response.TotalAvailableResults, (int)totalRecordsImported);
                }
            }

Its works better. 它的效果更好。

Please let me know if we can do it better than this. 请让我知道我们是否可以做得更好。

Thank you. 谢谢。

You can use sql bulk insert : 您可以使用sql批量插入:

DataTable table = new DataTable("States");
// construct DataTable
table.Columns.Add(new DataColumn("id_state", typeof(int))); 
table.Columns.Add(new DataColumn("state_name", typeof(string)));

// note: if "id_state" is defined as an identity column in your DB,
// row values for that column will be ignored during the bulk copy
table.Rows.Add("1", "Atlanta");
table.Rows.Add("2", "Chicago");
table.Rows.Add("3", "Springfield");

using(SqlBulkCopy bulkCopy = new SqlBulkCopy(connectionString))
{
  bulkCopy.BulkCopyTimeout = 600; // in seconds
  bulkCopy.DestinationTableName = "state";
  bulkCopy.WriteToServer(table);
}

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

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