zoukankan      html  css  js  c++  java
  • SqlBulkCopy 批量复制数据到数据库

    1.简介


    1.MSDN

    核心方法:SqlBulkCopy.WriteToServer

    将所有行从数据源复制到 SqlBulkCopy 对象的 DestinationTableName 属性指定的目标表中.

    2.一句话介绍

    将DataTable或DataRow中的数据直接复制到数据库中指定的表中

    3.注意事项

    1. 表名、列名对大小写敏感
    2. DataTable的架构必须和目标表保持一致(最常出的错误就是列顺序不一致)
    3. DataTable中int类型的字段如果为NULL,必须对其赋值为 DBNull.Value
    4. SqlBulkCopy遇到重复字段只会直接报错,然后默认回滚所有复制操作即复制到一半出错了,那整个前面复制也都放弃掉

    2.示例


    1.使用SqlBulkCopy

    调用格式

    SqlBulkCopyByDatatable(SQLAss.GetConnString(),"PartList", excelDt);
    

    SQLHelper类

    public SQLHelper()
    {
        //DatabaseTest 引用自web.config connectionStrings中
        string strconn = ConfigurationManager.ConnectionStrings["SQLAss"].ConnectionString;
        conn = new SqlConnection(strconn);
    }
     
    public string GetConnString()
    {
        return conn.ConnectionString;
    }
     
    

    Web.config
    注意必须要有:Persist Security Info=True

    <configuration>
      <connectionStrings>
        <add name="SQLAss" connectionString="Persist Security Info=True; SERVER=10.100.10.100;DATABASE=DBName;UID=userId;PWD=password;Connect Timeout=2880"
          providerName="System.Data.SqlClient" />
      </connectionStrings>
    </configuration>
    

    SqlBulkCopy

    public static void SqlBulkCopyByDatatable(string ConnectionString, string TableName, DataTable Dt)
    {
        using (SqlConnection conn = new SqlConnection(ConnectionString))
        {
            using (SqlBulkCopy sqlbulkcopy =new SqlBulkCopy(ConnectionString, SqlBulkCopyOptions.UseInternalTransaction))
            {
                try
                {
                    sqlbulkcopy.BulkCopyTimeout = 5000;//指定超时时间 以秒为单位 默认超时时间是30秒,设置为0即不限时间
                    sqlbulkcopy.DestinationTableName = TableName;//目标数据库表名
     
                    for (int i = 0; i < Dt.Columns.Count; i++)
                    {
                        //映射字段名 DataTable列名 ,数据库对应列名 
                        sqlbulkcopy.ColumnMappings.Add(Dt.Columns[i].ColumnName, Dt.Columns[i].ColumnName);
                    }
                    /*               
                    //额外,可不写:设置一次性处理的行数。这个行数处理完后,会激发SqlRowsCopied()方法。默认为1
                    //这个可以用来提示用户S,qlBulkCopy的进度
                    sqlbulkcopy.NotifyAfter = 1;
                    //设置激发的SqlRowsCopied()方法,这里为sqlbulkcopy_SqlRowsCopied 
                    sqlbulkcopy.SqlRowsCopied += new SqlRowsCopiedEventHandler(bulkCopy_SqlRowsCopied);
                    */
                    sqlbulkcopy.WriteToServer(Dt);//将数据源拷备到目标数据库
                }
                catch (System.Exception e)
                {
                    // throw e;
                    string eMessage=e.Message.ToString();
                    int indexLeft=eMessage.IndexOf("重复键值为 (")+7;
                    int indexRight=eMessage.IndexOf(")。");
                    int strLength = indexRight- indexLeft;
                    if (indexLeft!= -1)
                    {
                        throw new Exception("批量导入失败,存在重复记录:"+eMessage.Substring(indexLeft,strLength));
                    }
                    else
                    {
                        throw e;
                    }
     
                }
                finally
                {
                    conn.Close();
                }
            }
        }
    }
    

    2.重复字段处理

    直接报错或参考yudehui网友采用递归思想的跳过重复行继续复制

  • 相关阅读:
    mysql 中只能使用 localhost 登录,用ip不能登陆
    在springboot 和 mybatis 项目中想要显示sql 语句进行调试
    从一张表数据导入到另一张表
    mysql 中 delete 子查询的限制
    配置eureka 老是报错connected time out 或者 refused connected
    Linux-TCP 出现 RST 的几种情况
    MySQL-优化之 index merge(索引合并)
    Python-Mac 安装 PyQt4
    PHP-PHP-FPM的max_children一些误区
    Linux-磁盘及网络IO工作方式解析
  • 原文地址:https://www.cnblogs.com/moonache/p/5591922.html
Copyright © 2011-2022 走看看