• BCP 高效批量导入


    将oledb读取的excel数据快速插入的sqlserver中,很多人通过循环来拼接sql,这样做不但容易出错而且效率低下,最好的办法是使用bcp,也就是System.Data.SqlClient.SqlBulkCopy 类来实现。不但速度快,而且代码简单,下面测试代码导入一个6万多条数据的sheet,包括读取(全部读取比较慢)在我的开发环境中只需要10秒左右,而真正的导入过程只需要4.5秒。

    1. using System;   
    2. using System.Data;   
    3. using System.Windows.Forms;   
    4. using System.Data.OleDb;   
    5. namespace WindowsApplication2   
    6. {   
    7.     public partial class Form1 : Form   
    8.     {   
    9.         public Form1()   
    10.         {   
    11.             InitializeComponent();   
    12.         }   
    13.   
    14.         private void button1_Click(object sender, EventArgs e)   
    15.         {   
    16.             //测试,将excel中的sheet1导入到sqlserver中   
    17.             string connString = "server=localhost;uid=sa;pwd=sqlgis;database=master";   
    18.             System.Windows.Forms.OpenFileDialog fd = new OpenFileDialog();   
    19.             if (fd.ShowDialog() == DialogResult.OK)   
    20.             {   
    21.                 TransferData(fd.FileName, "sheet1", connString);   
    22.             }   
    23.         }   
    24.   
    25.         public void TransferData(string excelFile, string sheetName, string connectionString)   
    26.         {   
    27.             DataSet ds = new DataSet();   
    28.             try  
    29.             {   
    30.                 //获取全部数据   
    31.                 string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + excelFile + ";" + "Extended Properties=Excel 8.0;";   
    32.                 OleDbConnection conn = new OleDbConnection(strConn);   
    33.                 conn.Open();   
    34.                 string strExcel = "";   
    35.                 OleDbDataAdapter myCommand = null;   
    36.                 strExcel = string.Format("select * from [{0}$]", sheetName);   
    37.                 myCommand = new OleDbDataAdapter(strExcel, strConn);   
    38.                 myCommand.Fill(ds, sheetName);   
    39.   
    40.                 //如果目标表不存在则创建   
    41.                 string strSql = string.Format("if object_id('{0}') is null create table {0}(", sheetName);   
    42.                 foreach (System.Data.DataColumn c in ds.Tables[0].Columns)   
    43.                 {   
    44.                     strSql += string.Format("[{0}] varchar(255),", c.ColumnName);   
    45.                 }   
    46.                 strSql = strSql.Trim(',') + ")";   
    47.   
    48.                 using (System.Data.SqlClient.SqlConnection sqlconn = new System.Data.SqlClient.SqlConnection(connectionString))   
    49.                 {   
    50.                     sqlconn.Open();   
    51.                     System.Data.SqlClient.SqlCommand command = sqlconn.CreateCommand();   
    52.                     command.CommandText = strSql;   
    53.                     command.ExecuteNonQuery();   
    54.                     sqlconn.Close();   
    55.                 }   
    56.                 //用bcp导入数据   
    57.                 using (System.Data.SqlClient.SqlBulkCopy bcp = new System.Data.SqlClient.SqlBulkCopy(connectionString))   
    58.                 {   
    59.                     bcp.SqlRowsCopied += new System.Data.SqlClient.SqlRowsCopiedEventHandler(bcp_SqlRowsCopied);   
    60.                     bcp.BatchSize = 100;//每次传输的行数   
    61.                     bcp.NotifyAfter = 100;//进度提示的行数   
    62.                     bcp.DestinationTableName = sheetName;//目标表   
    63.                     bcp.WriteToServer(ds.Tables[0]);   
    64.                 }   
    65.             }   
    66.             catch (Exception ex)   
    67.             {   
    68.                 System.Windows.Forms.MessageBox.Show(ex.Message);   
    69.             }   
    70.   
    71.         }   
    72.   
    73.         //进度显示   
    74.         void bcp_SqlRowsCopied(object sender, System.Data.SqlClient.SqlRowsCopiedEventArgs e)   
    75.         {   
    76.             this.Text = e.RowsCopied.ToString();   
    77.             this.Update();   
    78.         }   
    79.   
    80.   
    81.     }   
    82. }   

    面的TransferData基本可以直接使用,如果要考虑周全的话,可以用oledb来获取excel的表结构,并且加入ColumnMappings来设置对照字段,这样效果就完全可以做到和sqlserver的dts相同的效果了。

    获取excel结构的方法,同理可以获得access等数据库的表结构信息  GetOleDbSchemaTable:
    using System;
    namespace ConsoleApplication11
    {
        
    class Program
        
    {
            
    public static void Main()
            
    {
                getExcelFileInfo(
    @"c:a.xls");
            }

            
    private static void getExcelFileInfo(string Path)
            
    {
                
    string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + Path + ";" + "Extended Properties=Excel 8.0;";
                System.Data.OleDb.OleDbConnection conn 
    = new System.Data.OleDb.OleDbConnection(strConn);
                conn.Open();
                System.Data.DataTable table 
    = conn.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables, null);

                
    foreach (System.Data.DataRow drow in table.Rows)
                
    {
                    
    string TableName = drow["Table_Name"].ToString();
                    Console.WriteLine(TableName
    +":");
                    System.Data.DataTable tableColumns 
    = conn.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Columns, new object[] nullnull, TableName ,null});
                    
    foreach (System.Data.DataRow drowColumns in tableColumns.Rows)
                    
    {
                        
    string ColumnName = drowColumns["Column_Name"].ToString();
                        Console.WriteLine(
    " "+ColumnName);
                    }

                }

                Console.ReadKey(
    true);
            }

        }

    }

    JDBC中对应是:
    rs=stmt.executeQuery(sql);
       rsMD=rs.getMetaData();

    for(int i=1;i<=rsMD.getColumnCount();i++)    
         if(rsMD.getColumnType(i)==4)//int类型
          xmlContent+=rsMD.getColumnName(i)+"='"+rs.getInt(rsMD.getColumnName(i))+"' ";
         else
          xmlContent+=rsMD.getColumnName(i)+"='"+rs.getString(rsMD.getColumnName(i))+"' ";

  • 相关阅读:
    格式化数据和DataBinder.Eval用法范例【转】
    动态GridView +DataTable
    Container.DataItem
    SQL自定义字段排序
    VS 2008 Web Deployment Project
    清除SQLServer日志
    SQL常用功能
    在Web应用程序中执行计划任务(多线程)
    得到临时表的列数
    用rdlc文件直接导出到excel或PDF
  • 原文地址:https://www.cnblogs.com/willpower/p/1244054.html
Copyright © 2020-2023  润新知