【问题标题】:exporting data to ms access accdb from sql takes long time从sql导出数据到ms access accdb需要很长时间
【发布时间】:2020-01-30 10:33:13
【问题描述】:

我有一个带有大约 10000 行的 stock 表的 SQL 数据库,我需要一个代码来复制所有行以更快地访问数据库文件 accdb。因为此代码将每天运行。

我下面的代码至少需要 5 分钟才能运行。

````````````````conn.Open();
                SqlDataAdapter ada2 = new SqlDataAdapter("select ITEMCODE,DESCRIPTION,ONHAND,COSTEXCL,COSTINCL,PRICEEXCL,PRICEINCL,LASTSOLD,LASTRECEIVED from stmast", conn);

                DataTable dt2 = new DataTable();
                ada2.Fill(dt2);

                for (int M = 0; M < dt2.Rows.Count; M++)
                {
                    DataRow dr2 = dt2.Rows[M];


                    OleDbCommand cmd2 = new OleDbCommand("INSERT INTO stmast(ITEMCODE,DESCRIPTION,ONHAND,COSTEXCL,COSTINCL,PRICEEXCL,PRICEincl,LASTSOLD,LASTRECEIVED)" + " VALUES('" + dr2["itemcode"].ToString() + "','" + dr2["description"].ToString() + "','" + dr2["onhand"].ToString() + "','" + dr2["costexcl"].ToString() + "','" + dr2["costincl"].ToString() + "','" + dr2["priceexcl"].ToString() + "','" + dr2["priceincl"].ToString() + "','" + dr2["lastsold"].ToString() + "','" + dr2["lastreceived"].ToString() + "');", objConn3);
                    cmd2.ExecuteNonQuery();
                }
                MessageBox.Show("done"); ```

【问题讨论】:

  • 不知道这是否对您可用,但使用 DAO 和 RecordSet.AddNew 这将在几秒钟(或几毫秒)内运行。
  • 复制的目的?你知道你可以链接 sql server 表来访问和使用实时数据吗?

标签: c# sql ms-access


【解决方案1】:

终于找到了出路,得到了一个通用的存储过程,可以将表数据从SQL复制到ms访问,它眨眼就可以了! 感谢丹麦人 Janjua

Exec dcp_Export_Table @sSrcTableName  = 'stmast' ,@sDestTableName = 'stmast' ,@sPathName  ='C:\Users\ABRAR AHMED\Desktop\test.mdb'


-------------------------------------------------------------------------------

IF EXISTS (SELECT name FROM   sysobjects WHERE  name = N'dcp_Export_Table' AND type = 'P')

    DROP PROCEDURE dcp_Export_Table

GO

CREATE PROCEDURE dcp_Export_Table

 @sSrcTableName  Varchar(100)

 ,@sDestTableName Varchar(100)

 ,@sPathName  Varchar(255)

AS

/*

Module      : dcp_Export_Table

Description : Export named table to named Access Mdb file

Modification History

====================

Date  Author  Description

--------------- --------------- ----------------------------------------------------------------------------

06-09-2005 Danish Janjua Created

*/

BEGIN

SET NOCOUNT ON

--

-- *** Logging & Error Check variables *** --

--

Declare

  @sDbName  sysname  -- Holds the Name of the Database where this procedure is being run

 ,@sProcedureName sysname  -- Procedure name, used for Logging

 ,@sStepName  Varchar(50) -- Step name within procedure, used for logging

 ,@sMessage  Varchar(255) -- Used for Procedure Logging

 ,@iError  Int  -- Error value

 ,@iRetVal  Int  -- Return values returned from SP or XP

 ,@sFirstTimeThru Char(1)

 ,@sColumnName  Varchar(50)

 ,@sTableColumnList Varchar(2000)

 ,@sSqlCommand  nVarchar(2000)

--

-- *** Initialise Process logging variables *** --

--

 Select @sDbName  = DB_NAME()

 Select @sProcedureName = OBJECT_NAME(@@Procid)

 Select @iError  = 0

 Select @iRetVal  = 0

 Set NoCount On

-----------------------------------------------------------------------------------------------------------------------

-- STEPA: PROCEDURE BEGIN

-----------------------------------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------------------------

-- STEPB: Create a comma delimited list of column names into a string

-----------------------------------------------------------------------------------------------------------------------

Select @sTableColumnList = ''

Select @sFirstTimeThru = 'Y'

Declare dcp_columns_cursor Cursor For

 Select  Column_Name

 From  Information_Schema.Columns

 Where  table_catalog  = @sDbName

 and  table_schema  = 'dbo'

 and table_name  = @sSrcTableName

Open dcp_columns_cursor

Fetch Next From dcp_columns_cursor  Into   @sColumnName

While @@FETCH_STATUS = 0

Begin

 If @sFirstTimeThru = 'Y'

  Begin

   Select @sTableColumnList = @sColumnName

   Select @sFirstTimeThru = 'N'

  End

 Else   

  Select @sTableColumnList = @sTableColumnList + ',' + @sColumnName

 Fetch Next From dcp_columns_cursor  Into   @sColumnName

End

Close dcp_columns_cursor

Deallocate dcp_columns_cursor

-----------------------------------------------------------------------------------------------------------------------

-- STEPC: Export table to Mdb file

-----------------------------------------------------------------------------------------------------------------------

Select @sSqlCommand = 'INSERT INTO OPENROWSET '

      + '(''Microsoft.ACE.OLEDB.12.0'','      -- provider

      + '''' + @sPathName + ''' ; ''Admin'' ; '''' '    -- path & access details

      + ', ' + @sDestTableName + ')'      -- destination table

      + ' (' + @sTableColumnList + ') '      -- column names

      + 'Select ' + @sTableColumnList + ' From ' +  @sSrcTableName + ' (NoLock)' -- source query

--

-- Execute it!

--

Execute sp_executesql @sSqlCommand

-----------------------------------------------------------------------------------------------------------------------

-- STEPZ: PROCEDURE END

-----------------------------------------------------------------------------------------------------------------------

NORMALEXIT:

Set NoCount Off

Return

END

【讨论】:

    【解决方案2】:

    您可以通过将 INSERT 命令分组并使用单个 DbCommand 执行它们来提高性能。

    您可以从如下更改代码开始。在这个版本中,您每 10 条记录执行一个带有 10 个 INSERT 查询的命令。

    conn.Open();
    SqlDataAdapter ada2 = new SqlDataAdapter("select ITEMCODE,DESCRIPTION,ONHAND,COSTEXCL,COSTINCL,PRICEEXCL,PRICEINCL,LASTSOLD,LASTRECEIVED from stmast", conn);
    
    DataTable dt2 = new DataTable();
    ada2.Fill(dt2);
    string sqlCmd = "";
    
    for (int M = 0; M < dt2.Rows.Count; M++)
    {
      DataRow dr2 = dt2.Rows[M];
      sqlCmd += "INSERT INTO stmast(ITEMCODE,DESCRIPTION,ONHAND,COSTEXCL,COSTINCL,PRICEEXCL,PRICEincl,LASTSOLD,LASTRECEIVED)" + " VALUES('" + dr2["itemcode"].ToString() + "','" + dr2["description"].ToString() + "','" + dr2["onhand"].ToString() + "','" + dr2["costexcl"].ToString() + "','" + dr2["costincl"].ToString() + "','" + dr2["priceexcl"].ToString() + "','" + dr2["priceincl"].ToString() + "','" + dr2["lastsold"].ToString() + "','" + dr2["lastreceived"].ToString() + "');";
    
      if (M % 10 == 0) 
      {
        OleDbCommand cmd2 = new OleDbCommand(sqlCmd); 
        cmd2.ExecuteNonQuery();
        sqlCmd = "";
      }
    }
    
    //Executes the last commands
    if (sqlCmd  != "") 
    {
      OleDbCommand cmd2 = new OleDbCommand(sqlCmd); 
      cmd2.ExecuteNonQuery();
    }
    
    MessageBox.Show("done"); ```
    

    如果此解决方案提高了性能,请考虑更改您创建的 SQL,语法如下:

     INSERT INTO stmast(...)
     SELECT [Records from the first dr2 row]
     UNION ALL
     SELECT [Records from the next dr2 row]
     UNION ALL
     SELECT [Records from the next dr2 row]
     [....]
    

    请参阅此线程以获取更多信息和其他可能的解决方案:Multiple Insert statements in one connection

    【讨论】:

    • Nicola Lepetit 似乎没有运行“在 sql 语句结束后找到的字符”
    【解决方案3】:

    在 Access 中打开数据库并在 SQL Server 中创建到源表的 ODBC 链接表。它可能会被赋予一个带有dbo_ 前缀的名称,例如dbo_stmast

    然后创建一个追加查询以将链接源表中的行追加到目标表中。它看起来像这样:

    然后,您可以通过将 C# 应用程序作为存储过程调用该已保存的 Append 查询来调用它:

    string connectionString =
          @"Provider=Microsoft.ACE.OLEDB.12.0;"
        + @"Data Source=C:\Users\Public\so59983979.accdb";
    using (var con = new OleDbConnection(connectionString))
    {
        con.Open();
        using (var cmd = new OleDbCommand())
        {
            cmd.Connection = con;
            cmd.CommandText = "append_my_table";
            cmd.CommandType = System.Data.CommandType.StoredProcedure;
            var sw = new Stopwatch();
            sw.Start();
            int rowCount = cmd.ExecuteNonQuery();
            sw.Stop();
            Console.WriteLine($"{rowCount} rows inserted in {sw.ElapsedMilliseconds} ms.");
            // 10000 rows inserted in 1014 ms.
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-08
      • 2019-04-25
      • 1970-01-01
      • 2016-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多