GVKun编程网logo

在.NET / C#中将大量记录(批量插入)写入Access(c# 批量写入数据库)

15

如果您想了解在.NET/C#中将大量记录和批量插入写入Access的知识,那么本篇文章将是您的不二之选。我们将深入剖析在.NET/C#中将大量记录的各个方面,并为您解答批量插入写入Access的疑在这

如果您想了解在.NET / C#中将大量记录批量插入写入Access的知识,那么本篇文章将是您的不二之选。我们将深入剖析在.NET / C#中将大量记录的各个方面,并为您解答批量插入写入Access的疑在这篇文章中,我们将为您介绍在.NET / C#中将大量记录的相关知识,同时也会详细的解释批量插入写入Access的运用方法,并给出实际的案例分析,希望能帮助到您!

本文目录一览:

在.NET / C#中将大量记录(批量插入)写入Access(c# 批量写入数据库)

在.NET / C#中将大量记录(批量插入)写入Access(c# 批量写入数据库)

从.NET向MS Access数据库执行批量插入的最佳方法是什么?使用ADO.NET,写一个大型数据集耗时一个多小时。

请注意,在“重构”之前,我的原始帖子在问题部分同时包含了问题和答案。 我接受了Igor Turman的建议,并将其分为两部分-
上面的问题,然后是我的答案。

答案1

小编典典

我发现以特定方式使用DAO的速度大约比使用ADO.NET快30倍。我正在共享代码并得到这个答案。作为背景,下面的测试是写出20列的表的100000条记录。

技术和时间的摘要-从好到坏:

  1. 02.8秒: 使用DAO,使用DAO.Field来引用表列
  2. 02.8秒: 写出到文本文件,使用自动化将文本导入Access
  3. 11.0秒: 使用DAO,使用列索引引用表列。
  4. 17.0秒: 使用DAO,按名称引用该列
  5. 79.0秒: 使用ADO.NET,为每一行生成INSERT语句
  6. 86.0秒: 使用ADO.NET,使用DataTable到DataAdapter进行“批量”插入

作为背景,有时我需要对相当大量的数据进行分析,我发现Access是最好的平台。该分析涉及许多查询,并且经常涉及许多VBA代码。

由于各种原因,我想使用C#代替VBA。典型的方法是使用OleDB连接到Access。我曾经使用OleDbDataReader来抓取数百万条记录,并且效果很好。但是,将结果输出到表时,需要花费很长时间。一个多小时。

首先,让我们讨论将记录从C#写入Access的两种典型方法。两种方式都涉及OleDB和ADO.NET。第一种是一次生成一个INSERT语句,然后执行它们,对100000条记录花费79秒。代码是:

public static double TestADONET_Insert_TransferToAccess(){  StringBuilder names = new StringBuilder();  for (int k = 0; k < 20; k++)  {    string fieldName = "Field" + (k + 1).ToString();    if (k > 0)    {      names.Append(",");    }    names.Append(fieldName);  }  DateTime start = DateTime.Now;  using (OleDbConnection conn = new OleDbConnection(Properties.Settings.Default.AccessDB))  {    conn.Open();    OleDbCommand cmd = new OleDbCommand();    cmd.Connection = conn;    cmd.CommandText = "DELETE FROM TEMP";    int numRowsDeleted = cmd.ExecuteNonQuery();    Console.WriteLine("Deleted {0} rows from TEMP", numRowsDeleted);    for (int i = 0; i < 100000; i++)    {      StringBuilder insertSQL = new StringBuilder("INSERT INTO TEMP (")        .Append(names)        .Append(") VALUES (");      for (int k = 0; k < 19; k++)      {        insertSQL.Append(i + k).Append(",");      }      insertSQL.Append(i + 19).Append(")");      cmd.CommandText = insertSQL.ToString();      cmd.ExecuteNonQuery();    }    cmd.Dispose();  }  double elapsedTimeInSeconds = DateTime.Now.Subtract(start).TotalSeconds;  Console.WriteLine("Append took {0} seconds", elapsedTimeInSeconds);  return elapsedTimeInSeconds;}

请注意,我在Access中找不到允许批量插入的方法。

然后我以为也许将数据表与数据适配器一起使用会很有用。特别是因为我以为可以使用UpdateBatchSize数据适配器的属性进行批量插入。但是,显然只有SQL
Server和Oracle支持,而Access不支持。它花费了最长的时间86秒。我使用的代码是:

public static double TestADONET_DataTable_TransferToAccess(){  StringBuilder names = new StringBuilder();  StringBuilder values = new StringBuilder();  DataTable dt = new DataTable("TEMP");  for (int k = 0; k < 20; k++)  {    string fieldName = "Field" + (k + 1).ToString();    dt.Columns.Add(fieldName, typeof(int));    if (k > 0)    {      names.Append(",");      values.Append(",");    }    names.Append(fieldName);    values.Append("@" + fieldName);  }  DateTime start = DateTime.Now;  OleDbConnection conn = new OleDbConnection(Properties.Settings.Default.AccessDB);  conn.Open();  OleDbCommand cmd = new OleDbCommand();  cmd.Connection = conn;  cmd.CommandText = "DELETE FROM TEMP";  int numRowsDeleted = cmd.ExecuteNonQuery();  Console.WriteLine("Deleted {0} rows from TEMP", numRowsDeleted);  OleDbDataAdapter da = new OleDbDataAdapter("SELECT * FROM TEMP", conn);  da.InsertCommand = new OleDbCommand("INSERT INTO TEMP (" + names.ToString() + ") VALUES (" + values.ToString() + ")");  for (int k = 0; k < 20; k++)  {    string fieldName = "Field" + (k + 1).ToString();    da.InsertCommand.Parameters.Add("@" + fieldName, OleDbType.Integer, 4, fieldName);  }  da.InsertCommand.UpdatedRowSource = UpdateRowSource.None;  da.InsertCommand.Connection = conn;  //da.UpdateBatchSize = 0;  for (int i = 0; i < 100000; i++)  {    DataRow dr = dt.NewRow();    for (int k = 0; k < 20; k++)    {      dr["Field" + (k + 1).ToString()] = i + k;    }    dt.Rows.Add(dr);  }  da.Update(dt);  conn.Close();  double elapsedTimeInSeconds = DateTime.Now.Subtract(start).TotalSeconds;  Console.WriteLine("Append took {0} seconds", elapsedTimeInSeconds);  return elapsedTimeInSeconds;}

然后我尝试了非标准方法。首先,我写了一个文本文件,然后使用自动化将其导入。这非常快-2.8秒-并列第一。但是由于许多原因,我认为它很脆弱:输出日期字段很棘手。我必须对它们进行特殊格式化(someDate.ToString("yyyy-MM-dd HH:mm")),然后设置一个特殊的“导入规范”以这种格式编码。导入规范还必须设置“
quote”定界符。在下面的示例中,只有整数字段,不需要导入规范。

文本文件对于“国际化”也很脆弱,在十进制分隔符,不同的日期格式以及可能使用unicode的地方都使用逗号。

请注意,第一条记录包含字段名称,因此列顺序不依赖于表,并且我们使用Automation来实际导入文本文件。

public static double TestTextTransferToAccess(){  StringBuilder names = new StringBuilder();  for (int k = 0; k < 20; k++)  {    string fieldName = "Field" + (k + 1).ToString();    if (k > 0)    {      names.Append(",");    }    names.Append(fieldName);  }  DateTime start = DateTime.Now;  StreamWriter sw = new StreamWriter(Properties.Settings.Default.TEMPPathLocation);  sw.WriteLine(names);  for (int i = 0; i < 100000; i++)  {    for (int k = 0; k < 19; k++)    {      sw.Write(i + k);      sw.Write(",");    }    sw.WriteLine(i + 19);  }  sw.Close();  ACCESS.Application accApplication = new ACCESS.Application();  string databaseName = Properties.Settings.Default.AccessDB    .Split(new char[] { '';'' }).First(s => s.StartsWith("Data Source=")).Substring(12);  accApplication.OpenCurrentDatabase(databaseName, false, "");  accApplication.DoCmd.RunSQL("DELETE FROM TEMP");  accApplication.DoCmd.TransferText(TransferType: ACCESS.AcTextTransferType.acImportDelim,  TableName: "TEMP",  FileName: Properties.Settings.Default.TEMPPathLocation,  HasFieldNames: true);  accApplication.CloseCurrentDatabase();  accApplication.Quit();  accApplication = null;  double elapsedTimeInSeconds = DateTime.Now.Subtract(start).TotalSeconds;  Console.WriteLine("Append took {0} seconds", elapsedTimeInSeconds);  return elapsedTimeInSeconds;}

最后,我尝试了DAO。那里的许多站点都对使用DAO发出了巨大的警告。但是,事实证明,这只是Access和.NET之间进行交互的最佳方法,尤其是当您需要写出大量记录时。此外,它还可以访问表的所有属性。我在某处读到,使用DAO而不是ADO.NET编程事务最简单。

注意,有几行代码被注释。他们将很快解释。

public static double TestDAOTransferToAccess(){  string databaseName = Properties.Settings.Default.AccessDB    .Split(new char[] { '';'' }).First(s => s.StartsWith("Data Source=")).Substring(12);  DateTime start = DateTime.Now;  DAO.DBEngine dbEngine = new DAO.DBEngine();  DAO.Database db = dbEngine.OpenDatabase(databaseName);  db.Execute("DELETE FROM TEMP");  DAO.Recordset rs = db.OpenRecordset("TEMP");  DAO.Field[] myFields = new DAO.Field[20];  for (int k = 0; k < 20; k++) myFields[k] = rs.Fields["Field" + (k + 1).ToString()];  //dbEngine.BeginTrans();  for (int i = 0; i < 100000; i++)  {    rs.AddNew();    for (int k = 0; k < 20; k++)    {      //rs.Fields[k].Value = i + k;      myFields[k].Value = i + k;      //rs.Fields["Field" + (k + 1).ToString()].Value = i + k;    }    rs.Update();    //if (0 == i % 5000)    //{      //dbEngine.CommitTrans();      //dbEngine.BeginTrans();    //}  }  //dbEngine.CommitTrans();  rs.Close();  db.Close();  double elapsedTimeInSeconds = DateTime.Now.Subtract(start).TotalSeconds;  Console.WriteLine("Append took {0} seconds", elapsedTimeInSeconds);  return elapsedTimeInSeconds;}

在这段代码中,我们为每个列(myFields[k])创建了DAO.Field变量,然后使用它们。花了2.8秒。或者,可以直接访问在注释行中找到的那些字段,rs.Fields["Field"+ (k + 1).ToString()].Value = i +k;从而将时间增加到17秒。将代码包装在事务中(请参见注释行)将其降至14秒。使用整数索引rs.Fields[k].Value = i +k;将其降至11秒。使用DAO.Field(myFields[k])和事务实际上花费了更长的时间,将时间增加到3.1秒。

最后,为了完整起见,所有这些代码都在一个简单的静态类中,并且using语句如下:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using ACCESS = Microsoft.Office.Interop.Access; // USED ONLY FOR THE TEXT FILE METHODusing DAO = Microsoft.Office.Interop.Access.Dao; // USED ONLY FOR THE DAO METHODusing System.Data; // USED ONLY FOR THE ADO.NET/DataTable METHODusing System.Data.OleDb; // USED FOR BOTH ADO.NET METHODSusing System.IO;  // USED ONLY FOR THE TEXT FILE METHOD

.net 批量插入 oracle 数据库

.net 批量插入 oracle 数据库

protected void SaveTest(Repeater repeater)
{
            string connstr = BLIT.DA.Common.DataBaseConnection.GetDBConnectoinStr();

            using (OracleConnection conn = new OracleConnection(connstr))
            {
                conn.Open();

                //主表插入语句
                OracleDataAdapter oda = new OracleDataAdapter();
                oda.SelectCommand = new OracleCommand(" select * from fdjh_zb where 1=2 " ,conn );
                oda.InsertCommand = new OracleCommand(" insert into fdjh_zb (JHGUID,JHLX,DWBM,DWMC,SJDWBM,JHRQ,BSSJ,BSR,SFCS,ZT) "+
                                                      " values (:JHGUID,:JHLX,:DWBM,:DWMC,:SJDWBM,:JHRQ,:BSSJ,:BSR,:SFCS,:ZT)", conn);

                oda.InsertCommand.Parameters.Add(":JHGUID", OracleType.VarChar, 40, "JHGUID");
                oda.InsertCommand.Parameters.Add(":JHLX", OracleType.VarChar, 40, "JHLX");
                oda.InsertCommand.Parameters.Add(":DWBM", OracleType.VarChar, 40, "DWBM");
                oda.InsertCommand.Parameters.Add(":DWMC", OracleType.VarChar, 40, "DWMC");
                oda.InsertCommand.Parameters.Add(":SJDWBM", OracleType.VarChar, 40, "SJDWBM");
                oda.InsertCommand.Parameters.Add(":JHRQ", OracleType.VarChar, 40, "JHRQ");
                oda.InsertCommand.Parameters.Add(":BSSJ", OracleType.DateTime, 40, "BSSJ");
                oda.InsertCommand.Parameters.Add(":BSR", OracleType.VarChar, 40, "BSR");
                oda.InsertCommand.Parameters.Add(":SFCS", OracleType.Int32, 40, "SFCS");
                oda.InsertCommand.Parameters.Add(":ZT", OracleType.Int32, 40, "ZT");

                oda.InsertCommand.UpdatedRowSource = UpdateRowSource.None;
                oda.UpdateBatchSize = 0;

                DataSet ds = new DataSet();
                oda.Fill(ds);


                //主表插入语句变量声明
                string JHGUID = "";
                string JHZQ = "";
                string JHRQ = this.tbDate.Text;
                string JHLX = "";
                string DWBM = "";
                string DWMC = "";
                string SJDWBM = "";
                DateTime BSSJ = DateTime.Now;
                string BSR = "";
                int SFCS = 0;
                int ZT = 0;

                for (int i = 0; i < repeater.Items.Count; i++)
                {
                    //插入计划主表新记录
                    GridView gv = repeater.Items[i].FindControl("GridView1") as GridView;
                    string Orgcode = getLabelControl(gv, 0, "lbORGCODE").Text;
                    QX_ORGANIZATION QX_ORGANIZATION = QX_ORGANIZATION_bl.getByCode(Orgcode);

                    JHGUID = System.Guid.NewGuid().ToString("N");
                    JHZQ = this.RadioButtonList1.SelectedItem.Text;
                    DWBM = QX_ORGANIZATION.ORGCODE;
                    DWMC = QX_ORGANIZATION.ORGNAME;
                    SJDWBM = QX_ORGANIZATION.ADMINISTRATOR_ORG_CODE;
                    BSR = "";

                    switch (JHZQ)
                    {
                        case "日":
                            JHLX = "ZDDC-RJH";
                            break;
                        case "月":
                            JHLX = "ZDDC-YJH";
                            break;
                        case "年":
                            JHLX = "ZDDC-NJH";
                            break;
                        default:
                            break;

                    }
                    object[] row_zb = { JHGUID,JHLX,DWBM,DWMC,SJDWBM,JHRQ,BSSJ,BSR,SFCS,ZT };
                    ds.Tables[0].Rows.Add(row_zb);

                }

                //插入记录,回收资源
                oda.Update(ds.Tables[0]);
                ds.Tables[0].Clear();

                ds.Dispose();
                oda.Dispose();
               
                conn.Close();

            }
        }

Access 删除重复记录(删除多余记录)

Access 删除重复记录(删除多余记录)

Access数据库删除重复记录,只保留一条记录的做法: 

只保留id最小的记录方法:

delete from [表名] where id not in (select min(id) from [表名] group by [带重复记录的字段名称])

只保留id最大的记录方法:

delete from [表名] where id not in (select max(id) from [表名] group by [带重复记录的字段名称])

 

具体操作方法如下:

1、打开Access文件;

2、点击“安全警告”的“选项”;

 

3、启动VBA

 

4、选择菜单上的“创建”->“查询设计”

 

5、选择“sql”视图方式;

 

6、输入sql语句:

 

7、点击运行:

asp.net Ibatis.net 批量插入数据ORACLE

asp.net Ibatis.net 批量插入数据ORACLE

在开发中我们有时会遇到需要批量插入数据,最普通的就是每次 插入一条。但是当数据量大到一定的地步会很影响性能。下面例子示范了ibatis.net批量插入

ibatis.net 的XML文件里面使用iterate

<!--插入参数为ArrayList-->
<insert id="InsertUSER" parameterClass="ArrayList">
      Insert Into USER(
      ID,NAME)
      select * from (
      <iterate conjunction="UNION ALL" >
      select #[].ID#
        ,#[].NAME#
        from dual        
      </iterate>   )a

 

asp.net – 在MS Access中双重插入?

asp.net – 在MS Access中双重插入?

我以某种方式获得双重插入;每次我提交表单时,它都会向数据库发送两条记录.我无法弄清楚发生了什么.这是我的代码的一般概念:

Protected Sub btnSubmit_Click(ByVal sender As Object,ByVal e As System.EventArgs) Handles btnSubmit.Click

'Data collection'

'Define Connection'
    Dim myConn As New OleDbConnection
    myConn.ConnectionString = adsGrandmaster.ConnectionString
    myConn.open()

'Insert command'
    Dim myIns1 As New OleDbCommand("INSERT INTO tableGrandmaster (date_received,prefix,course_number,title,new,changed,inactivate,end_date,credits,description,hours_lecture,hours_lec_lab,hours_lab,hours_total,related_instruction,repeat,challengeable,in_catalog,in_printed_schedule,core_course,core_name,program_elective,program_name,prereqs,coreqs,recommended,green_course,code,dept_code,division_code,changing_depts,acti_code,grading,general_ed,writing,social_science,math,information_literacy,arts_letters,science_computer,speech_comm,cultural_literacy,date_curriculum_approval,date_state_sent,date_state_approval,date_created) VALUES (?,?,?)",myConn)

'Insert parameters'

'Execute command'
    myIns1.ExecuteNonQuery()

'Close connection'
    myConn.Close()

更新:

我的.aspx.vb文件的最后一小部分:

'Execute command'
    myIns1.ExecuteNonQuery()

    Label1.Text = "Grandmaster submitted."

    'Close connection'
    myConn.Close()

End Sub

Protected Sub btnBack_Click(ByVal sender As Object,ByVal e As System.EventArgs) Handles btnBack.Click
    Response.Redirect("./index.htm")
End Sub
End Class

如果我将断点放在myIns1.ExecuteNonQuery()之前或之前,则不会插入任何内容.如果我将它放在myIns1.ExecuteNonQuery()之后,它会插入一次.如果我将它放在“End Sub”之后(在myConn.Close()下),它会插入两次.

解决方法

确保aspx:button声明没有连接到前端页面上的onclick事件以及页面后面的代码.

今天关于在.NET / C#中将大量记录批量插入写入Access的介绍到此结束,谢谢您的阅读,有关.net 批量插入 oracle 数据库、Access 删除重复记录(删除多余记录)、asp.net Ibatis.net 批量插入数据ORACLE、asp.net – 在MS Access中双重插入?等更多相关知识的信息可以在本站进行查询。

本文标签: