无法执行批量插入操作 [英] cannot perform batch insert operations

查看:104
本文介绍了无法执行批量插入操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个从excel文件中提取记录的应用程序.
必须从excel文件将大约1000条记录插入数据库.
我将记录存储在大约4个集合中(每个集合代表一行),所以我有一个SqlDataAdapter,以便可以一次将记录插入.

明智地在后端创建了一个存储过程,该存储过程随后用于执行插入操作.

I have an application that extracts records from an excel file.
There are about 1000 records which must be inserted into a database from the excel file.
I store the records in about 4 collections (each one representing a row) so I have an SqlDataAdapter so that I can insert the records in one go.

Backend wise I created a stored procedure which is then used to perform the insert operation.

CREATE PROCEDURE [dbo].[spAddDebtor] 
@name char(50),
@person char(50),
@number char(50),
@address char(255)

AS
IF EXISTS(SELECT * FROM dbo.Debtor WHERE Debtor_Name = @Name)
     RETURN
INSERT INTO DEBTOR (Debtor_Name, Contact_Person, Contact_number,  Contact_Address)

VALUES (@name, @person, @number, @address)
GO



在C#中,我使用此方法



and in C# I use this method

// Insert records into database
        private void insertRecords()
        {
            // populate collections from Excel file
            populateAddress();
            populateContactPerson();
            populateNames();
            populatePhones();

            string sql = "SELECT * FROM DEBTOR";

            // Create data adapter
            SqlDataAdapter da = new SqlDataAdapter(sql, ConnectionString);

            // Create and fill dataset
            DataSet ds = new DataSet();
            da.Fill(ds, "debtor");
            
            // Get data table reference
            DataTable dt = ds.Tables["debtor"];

            sCommand.UpdatedRowSource = UpdateRowSource.None;

            SqlDataAdapter adpt = new SqlDataAdapter();

            
            try
            {
                // iterate through all records 
                // and perform insert on each iteration
                for (int i = 0; i < names.Count; i++)
                {
                    
                   
                   
                    sCommand.Parameters.AddWithValue
                           ("@debtor_name", Names[i].ToString());
                    sCommand.Parameters.AddWithValue
                           ("@contact_person", ContactPeople[i].ToString());
                    sCommand.Parameters.AddWithValue
                           ("@contact_number", Phones[i].ToString());
                    sCommand.Parameters.AddWithValue
                           ("@contact_address", Addresses[i].ToString());

                    

                   

                }

                adpt.InsertCommand = sCommand;

                

                // Specify the batch size
                Size = Names.Count;
                adpt.UpdateBatchSize = size;

                // Open the connection
                objConnection.Open();
                RowsAffected = adpt.Update(dt); // Execute the statement and show
                                                // number of rows affected
                objConnection.Close();
                
               
                

            }
            catch (SqlException ex)
            {
                throw ex;

            }
            finally
            {
                // Realease resources
                objConnection = null;
                objCommand = null;
                sCommand = null;
                sConnection = null;
                adpt = null;
                dt = null;
                ds = null;
                da = null;

            }
            
        }



问题是此代码运行没有错误,但是在数据库中没有新记录.
我尝试放置断点来检查集合中是否填充了excel数据,并且看起来它们实际上确实具有完全没有插入的数据.

我从sql本身测试了sproc,它似乎正常工作,没有人对我该如何提出建议吗?



The thing is this code runs with no errors but in the database the new records are not there.
I tried putting break point to check if the collections where populated with the excel data and it appears that they infact have the data the insertion is simply not happening.

I tested the sproc from sql itself at it seems to work with no problems does anyone have a suggestion as to how I can go about it?

推荐答案

代码
for (int i = 0; i < names.Count; i++)
               {



                   sCommand.Parameters.AddWithValue
                          ("@debtor_name", Names[i].ToString());
                   sCommand.Parameters.AddWithValue
                          ("@contact_person", ContactPeople[i].ToString());
                   sCommand.Parameters.AddWithValue
                          ("@contact_number", Phones[i].ToString());
                   sCommand.Parameters.AddWithValue
                          ("@contact_address", Addresses[i].ToString());





               }


您正在遍历名称列表并将参数添加到sCommnand对象.
如果直接运行sCommand.ExecuteNonQuery();,它将抛出异常,因为存储过程中实际指定的参数比实际指定的要多.

你也在打电话


You are Looping through the names List and adding parameter to sCommnand object.
If you directly run sCommand.ExecuteNonQuery();, it will throw an exception as there are more parameters than actually specified int the Stored Procedure.

Also you are calling

RowsAffected = adpt.Update(dt);


在您的代码中,没有sCommand & dt 对象.
adpt.InsertCommand = sCommand;在这种情况下是没有意义的,因为dt 没有添加额外的行.


解决方案1:
你可能会这样称呼


From your code there is no relation of sCommand & dt object.
adpt.InsertCommand = sCommand; is meaningless in this context beacuse dt has no extra rows added.


Solution 1:
you may call like this

for (int i = 0; i &lt; names.Count; i++)
               {



                   sCommand.Parameters.AddWithValue
                          ("@debtor_name", Names[i].ToString());
                   sCommand.Parameters.AddWithValue
                          ("@contact_person", ContactPeople[i].ToString());
                   sCommand.Parameters.AddWithValue
                          ("@contact_number", Phones[i].ToString());
                   sCommand.Parameters.AddWithValue
                          ("@contact_address", Addresses[i].ToString());

//New Code to directly call the stored procedures
               sCommand.ExecuteNonQuery();
               sCommand.Parameters.Clear();

               }

//Comment following lines

/*
                //Specify the batch size
                Size = Names.Count;
                adpt.UpdateBatchSize = size;

                // Open the connection
                objConnection.Open();
                RowsAffected = adpt.Update(dt); 
                // Execute the statement and show
                // number of rows affected
                objConnection.Close();

*/



解决方案2:



Solution 2:

for (int i = 0; i < names.Count; i++)
    {



             /* sCommand.Parameters.AddWithValue
                     ("@debtor_name", Names[i].ToString());
              sCommand.Parameters.AddWithValue
                     ("@contact_person", ContactPeople[i].ToString());
              sCommand.Parameters.AddWithValue
                     ("@contact_number", Phones[i].ToString());
              sCommand.Parameters.AddWithValue
                     ("@contact_address", Addresses[i].ToString());
        */

            //New Code for sol 2 :
            DataRow f = dt.NewRow();
            f["@debtor_name"] = Names[i].ToString();
            f["@contact_person"] = ContactPeople[i].ToString();
            f["@contact_number"] = Phones[i].ToString();
            f["@contact_address"] = Addresses[i].ToString();

            dt.Rows.Add(f);



  }

         // Specify the batch size
         Size = Names.Count;
         adpt.UpdateBatchSize = size;   // NOW THIS WILL BE CALLED ..

         // Open the connection
         objConnection.Open();
         RowsAffected = adpt.Update(dt); // Execute the statement and show
                                         // number of rows affected
         objConnection.Close();


您是否授予使用连接字符串的用户权限来执行SP?

抱歉,在使用Linq时无法为您提供代码.
Did you give rights to the user used in the connection string to execute the SP?

Sorry cannot help you with the code as I use Linq.


这篇关于无法执行批量插入操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆