1. 有标识列的表

1.1 SqlBulkCopyOptions.KeepIdentity  必须设置!否则会出现复制过去的数据产生标识列发现变化的情况!

1.2 如果原表的标识列即为主键, 那按1.1 的设置已足够。 如果原表无主键, 那在复制之前必须先清空原表(truncate table), 否则会出现多个相同的标识值的列!

2. 为NULL值的列

2.1 SqlBulkCopyOptions.KeepNulls 必须设置!否则会出现源数据的字段为NULL时, 复制过去却成了默认值!

其它几个选项的说明与分析:

Default  对所有选项使用默认值。  
 KeepIdentity 保留源标识值。如果未指定,则由目标分配标识值。  
 CheckConstraints  请在插入数据的同时检查约束。默认情况下,不检查约束。  
 TableLock  在批量复制操作期间获取批量更新锁。如果未指定,则使用行锁。  
 KeepNulls 保留目标表中的空值,而不管默认值的设置如何。如果未指定,则空值将由默认值替换(如果适用)。  
 FireTriggers  指定后,会导致服务器为插入到数据库中的行激发插入触发器。  默认情况下, 是不激发触发器的……
 UseInternalTransaction  如果已指定,则每一批批量复制操作将在事务中发生。 在一个事务中执行,要么都成功,要么都不成功

Default 就没有什么好说的了, 不要

KeepIdentity  和 KeepNulls
 上面已有了, 不再分析。

CheckConstraints
不需要, 因为是现成的数据, 既然已在DB中, 必然是通过了约束检查的。

TableLock
不需要, 因为复制时两个库都需要处于单连接状态, 不可能有干扰。

FireTriggers
 一般就不需要了吧, 毕竟只是复制数据, 而且是现成的数据……

UseInternalTransaction
 关系也不大, 反正复制失败会记录到自定义的日志, 失败了也知道, 重来一次就可以了。

下面是便于测试的代码

SQL:

--1. 建数据来源表
IF EXISTS (
SELECT 1 FROM sysobjects
WHERE id = OBJECT_ID(N'Table_1')
AND OBJECTPROPERTY(id, N'IsUserTable') = 1
)
BEGIN
DROP TABLE Table_1
END
GO
Create Table Table_1(
ID INT,
[NAME] VARCHAR(50) DEFAULT('xx')
)
GO
INSERT INTO Table_1
SELECT 1,'a' UNION
SELECT 2,'b' UNION
SELECT 3,'c' UNION
SELECT 4,'d' UNION
SELECT 5,'e' UNION
SELECT 6,null --2. 建目标表
IF EXISTS (
SELECT 1 FROM sysobjects
WHERE id = OBJECT_ID(N'Table_2')
AND OBJECTPROPERTY(id, N'IsUserTable') = 1
)
BEGIN
DROP TABLE Table_2
END
GO
Create Table Table_2(
ID2 INT,
[NAME2] VARCHAR(50) DEFAULT('xx')
)
GO --复制时的对应关系
--Tabe_1 ==> Table_2
--ID ==> ID2
--[NAME] ==> [NAME2]

C# 控制台程序:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Collections; namespace SqlBulkCopyDemo
{
class Program
{
static void Main(string[] args)
{
string connString = System.Configuration.ConfigurationManager.AppSettings["DCString"];
SqlConnection ConnectionNew = new SqlConnection(connString);
SqlConnection ConnectionOld = new SqlConnection(connString);
bool ExportInfo = System.Configuration.ConfigurationManager.AppSettings["ExportInfo"].ToLower()=="true";
try
{
ConnectionNew.Open();
ConnectionOld.Open(); //1.在旧表中,用SqlDataReader读取出信息
string SQL = "select * from Table_1"; SqlCommand cmd = new SqlCommand(SQL, ConnectionOld);
cmd.CommandTimeout = ;
SqlDataReader sdr = cmd.ExecuteReader(); //2.初始化SqlBulkCopy对象,用新的连接作为参数。
SqlBulkCopy bulkCopy = new SqlBulkCopy(ConnectionNew, SqlBulkCopyOptions.KeepIdentity | SqlBulkCopyOptions.KeepNulls, null);
bulkCopy.BulkCopyTimeout = ; //3.写对应关系。如旧表的People列的数据,对应新表Human列,那么就写bulkCopy.ColumnMappings.Add("People","Human")
//如果两张表的结构一样,那么对应关系就不用写了。
//我是用哈希表存储对应关系的,哈希表作为参数到传入方法中,key的值用来存储旧表的字段名,VALUE的值用来存储新表的值
Hashtable ht = new Hashtable();
ht.Add("ID", "ID2");
ht.Add("NAME", "NAME2");// foreach (string str in ht.Keys)
{
bulkCopy.ColumnMappings.Add(str, ht[str].ToString());
} //4.设置目标表名
bulkCopy.DestinationTableName = "Table_2"; //额外,可不写:设置一次性处理的行数。这个行数处理完后,会激发SqlRowsCopied()方法。默认为1
bulkCopy.NotifyAfter = ; if (ExportInfo)
{
//额外,可不写:设置激发的SqlRowsCopied()方法,这里为bulkCopy_SqlRowsCopied
bulkCopy.SqlRowsCopied += new SqlRowsCopiedEventHandler(bulkCopy_SqlRowsCopied);
} //OK,开始传数据!
DateTime dt = DateTime.Now;
Console.WriteLine("开始时间:{0:yyyy-MM-dd HH:mm:ss,ms}", dt);
bulkCopy.WriteToServer(sdr);
DateTime dt2 = DateTime.Now;
Console.WriteLine("结束时间:{0:yyyy-MM-dd HH:mm:ss,ms}", dt2);
double time = dt2.Subtract(dt).TotalMilliseconds;
Console.WriteLine("传输完毕!所用时间为:{0}(ms)", time);
Console.Read();
}
catch (Exception ex)
{
Console.Write(ex.Message);
Console.Read();
}
finally
{
ConnectionNew.Close();
ConnectionOld.Close();
}
} //激发的方法写在外头
private static void bulkCopy_SqlRowsCopied(object sender, SqlRowsCopiedEventArgs e)
{
//执行的内容。
//这里有2个元素值得拿来用
//e.RowsCopied, //返回数值类型,表示当前已经复制的行数
//e.Abort, //用于赋值true or false,用于停止赋值的操作
Console.WriteLine("当前已复制的行数:" + e.RowsCopied);
}
}
}

配置文件:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="DCString" value="Data Source=(local);Initial Catalog=db_Study;Persist Security Info=True;User ID=??;Password=??" />
<add key="ExportInfo" value="false" />
</appSettings>
</configuration>

 
 
************转载:https://blog.csdn.net/yenange/article/details/35837247

SqlBulkCopy使用注意事项的更多相关文章

  1. SqlBulkCopy使用介绍以及注意事项

    SqlBulkCopy,微软提供的快速插入类,针对大批量数据操作,此类效果明显有所提升,以下是微软官方解释: Microsoft SQL Server 提供一个称为 bcp 的流行的命令提示符实用工具 ...

  2. 数据库调优过程(一):SqlServer批量复制(bcp)[C#SqlBulkCopy]性能极低问题

    背景 最近一段给xx做项目,这边最头疼的事情就是数据库入库瓶颈问题. 环境 服务器环境:虚拟机,分配32CPU,磁盘1.4T,4T,5T,6T几台服务器不等同(转速都是7200r),内存64G. 排查 ...

  3. SqlBulkCopy 批量复制数据到数据库

    1.简介 1.MSDN 核心方法:SqlBulkCopy.WriteToServer 将所有行从数据源复制到 SqlBulkCopy 对象的 DestinationTableName 属性指定的目标表 ...

  4. 海量数据插入数据库效率对照測试 ---ADO.NET下SqlBulkCopy()对照LINQ 下InsertAllOnSubmit()

    摘要:使用.NET相关技术向数据库中插入海量数据是经常使用操作.本文对照ADO.NET和LINQ两种技术.分别使用SqlBulkCopy()和InsertAllOnSubmit()方法进行操作. 得出 ...

  5. 【ITOO 1】SQLBulkCopy实现不同数据库服务器之间的批量导入

    导读:在做项目的时候,当实现了动态建库后,需要实现从本地服务器上获取数据,批量导入到新建库的服务器中的一个表中去.之前是用了一个SQL脚本文件实现,但那时候没能实现不同的数据库服务器,现在用了SqlB ...

  6. jQuery UI resizable使用注意事项、实时等比例拉伸及你不知道的技巧

    这篇文章总结的是我在使用resizable插件的过程中,遇到的问题及变通应用的奇思妙想. 一.resizable使用注意事项 以下是我在jsfiddle上写的测试demo:http://jsfiddl ...

  7. Windows Server 2012 NIC Teaming介绍及注意事项

    Windows Server 2012 NIC Teaming介绍及注意事项 转载自:http://www.it165.net/os/html/201303/4799.html Windows Ser ...

  8. TODO:Golang指针使用注意事项

    TODO:Golang指针使用注意事项 先来看简单的例子1: 输出: 1 1 例子2: 输出: 1 3 例子1是使用值传递,Add方法不会做任何改变:例子2是使用指针传递,会改变地址,从而改变地址. ...

  9. app开发外包注意事项,2017最新资讯

    我们见过很多创业者,栽在这app外包上.很多创业者对于app外包这件事情不是特别重视,以为将事情交给app外包公司就完事了,实际上不是的.无论是从选择app外包公司还是签订合同.售后维护等各方面都有许 ...

随机推荐

  1. pl/sql基础语法

  2. python文件处理-读、写

    Python中文件处理的操作包括读.写.修改,今天我们一起来先学习下读和写操作. 一.文件的读操作 例一: #文件读操作 f = open(file="first_blog.txt" ...

  3. 斐波那契数列,跳台阶(dp思想)

    一 . 斐波那契数列:1,1,2,3,5,8,13,21 即后一项是前两项的和. class Solution { private: ]; public: Solution() { memset(ar ...

  4. 【bzoj3670】[Noi2014]动物园

    3670: [Noi2014]动物园 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 2080  Solved: 1107[Submit][Status ...

  5. Linux 下五款出色的流媒体客户端

    数 字流媒体这几天几乎占据了我音乐收听的全部时间.近年来我为了收藏 CD 花费了数量可观的费用:但它们中的大部分现在正静静地躺在满是灰尘的角落里.基本上所有的音乐流媒体服务所提供的的音质都不如 CD ...

  6. solidity mapping of mapping

    solidity mapping of mapping,两层映射,用的时候可以像二维数组一样去访问和修改值,非常方便. 以下代码示例中的这一句: mapping(string => mappin ...

  7. 3.Hive中查看数据来源文件和具体位置方法

    虚拟列 -- 当 hive 产生了非预期的或 null 的时候,可以通过虚拟列进行诊断,判断哪行数据出现问题 INPUT__FILE__NAME     (输入文件名)map任务读入File的全路径 ...

  8. 1.sql简介

    在总结sql语句前,说点无聊的哈哈 SQL 是用于访问和处理数据库的标准的计算机语言. SQL 能做什么? SQL 面向数据库执行查询 SQL 可从数据库取回数据 SQL 可在数据库中插入新的记录 S ...

  9. 在aspx页面中使用三元表达式

    第一种使用方法:判断GridView绑定的数据是否为空 用GridView或其他控件绑定数据的时候,有时候需要判断从数据库中获取的值是否是空值,然后显示相应的内容,如果在后置代码中写的话只有是在Row ...

  10. linux安装JDK后发现系统带有openjdk的处理

    1.JDK下载. 官网下载网址:https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html ...