如何在C#中更新MDB文件中的数千条记录

时间:2014-02-18 16:17:36

标签: c# ms-access oledb

我最近问过question有关如何在C#中的MDB文件中插入100,000条记录的问题。给定的答案将所需时间从45秒减少到10秒。甚至可以使用数字表将其缩短到2~3秒。

现在我在更新类似的数据库时遇到了问题。我不想在这种情况下实际更新100,000条记录,但是已经创建的MDB文件中有大约10,000条记录,包含100,1000条记录。

这是我的代码:

Stopwatch sw = new Stopwatch();
sw.Start();
OleDbConnection con = new OleDbConnection();
string dbProvider = "PROVIDER=Microsoft.Jet.OLEDB.4.0;";
string dbSource = "Data Source = D:/programming/sample.mdb";
con.ConnectionString = dbProvider + dbSource;
con.Open();
string query = "SELECT * FROM tblBooks";

DataSet ds = new DataSet();
OleDbDataAdapter da = new OleDbDataAdapter(query, con);
da.Fill(ds,"Books Table");
for (int i = 0; i < 10000; i++)
{
    ds.Tables[0].Rows[i][1] = "Book" + i.ToString();    
}


OleDbCommandBuilder cb = new OleDbCommandBuilder(da);
da.UpdateCommand = cb.GetUpdateCommand();
da.Update(ds, "Books Table");

con.Close();
sw.Stop();
Console.WriteLine(String.Format("{0:0.0} seconds", sw.ElapsedMilliseconds / 1000.0));

更新10000条记录(只有一个字段)需要大约24秒!

我有另一个表现良好的代码:

Stopwatch sw = new Stopwatch();
sw.Start();
OleDbConnection con = new OleDbConnection();
string dbProvider = "PROVIDER=Microsoft.Jet.OLEDB.4.0;";
string dbSource = "Data Source = D:/programming/sample.mdb";
con.ConnectionString = dbProvider + dbSource;
OleDbCommand cmd = new OleDbCommand();
cmd.Connection = con;
con.Open();
cmd.CommandText = "UPDATE tblBooks SET [Title] = @title";
cmd.Parameters.AddWithValue("@title", "Book");
cmd.ExecuteNonQuery();
con.Close();
sw.Stop();
Console.WriteLine(String.Format("{0:0.0} seconds", sw.ElapsedMilliseconds / 1000.0));

我发现当我使用上面的代码时,我能够在不到一秒钟(0.4秒)内更新整个表格(100,000条记录)。但在这个版本中,我不知道如何选择,只更新表的一部分以及如何为每个记录分配不同的值(Book 1,Book 2 ...)。我的意思是我希望能够更新表格中的记录4000到14000,并将Book 1,Book 2和...分配给title字段。

1 个答案:

答案 0 :(得分:3)

只是给你另一个选择考虑(正如4dmonster对你之前的问题的评论所建议的)这里是更新Access数据库的DAO Recordset方法。它“跳过”前4,000条记录并将下一万条更新为“Book 1”,“Book 2”,....

在许多情况下,DAO仍然是在Access数据库上执行逐行更新的最快方法。在我的机器上,以下代码需要2.5秒才能执行。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DAO;

namespace daoConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            var sw = new System.Diagnostics.Stopwatch();
            sw.Start();

            // This code requires the following COM reference in your project:
            //     Microsoft DAO 3.6 Object Library
            //
            var dbe = new DBEngine();
            Database db = dbe.OpenDatabase(@"C:\Users\Gord\Desktop\speed.mdb");
            Recordset rst = db.OpenRecordset(
                    "SELECT TOP 4001 ID FROM tblBooks ORDER BY ID",
                    RecordsetTypeEnum.dbOpenSnapshot);
            rst.MoveLast();
            int startID = rst.Fields["ID"].Value;
            rst.Close();
            rst = db.OpenRecordset(
                    String.Format(
                        "SELECT TOP 10000 Title FROM tblBooks WHERE ID >= {0} ORDER BY ID", 
                        startID),
                    RecordsetTypeEnum.dbOpenDynaset);
            int i = 1;
            while (!rst.EOF)
            {
                rst.Edit();
                rst.Fields["Title"].Value = String.Format("Book {0}", i++);
                rst.Update();
                rst.MoveNext();
            }
            rst.Close();

            sw.Stop();
            Console.WriteLine(String.Format("{0:0.0} seconds", sw.ElapsedMilliseconds / 1000.0));
        }
    }
}