原文:.net使用SqlBulkCopy导入数据(创建新表)

.net2.0后ado.net提供了一个快速导入sqlserver的方法sqlbulkcopy.导入效率非常高. 

包装了一个简单的sqlbulkcopy类,用于数据从datatable导入到sqlserver.代码如下:

    /// <summary>
/// 将DataTable写入数据库的表中
/// </summary>
/// <param name="source">数据源DataTable</param>
/// <param name="tableName">数据目标的表名</param>
/// <param name="useTransaction">操作过程是否使用事务</param>
/// <param name="databaseConnString">数据库连接字符串</param>
/// <param name="dropTable">删除DB中已存在的表(并自动新建表)</param>
/// <param name="primaryKeys">主键的列名</param>
public void WriteToDataBase(DataTable source, string tableName, bool useTransaction, string databaseConnString, bool dropTable, string[] primaryKeys)
{
//判断表是否存在
SqlHelper.ConnectionString = databaseConnString;
//dataHelper.IsConnString = true; //使用数据库连接字符串创建sqlserver操作对象
string sql = "select * from sys.objects where type='U' and name='" + tableName + "'";
DataTable dt = SqlHelper.ExecuteDataset(sql).Tables[];
if (dt.Rows.Count > )
{
if (dropTable == true)
{
sql = "drop table " + tableName + ""; //清除已存在的表
SqlHelper.ExecuteNonQuery(SqlHelper.ConnectionString, CommandType.Text, sql);
}
else
{
SqlBulkCopy sqlbulkcopy = new SqlBulkCopy(databaseConnString, SqlBulkCopyOptions.UseInternalTransaction | SqlBulkCopyOptions.FireTriggers);
sqlbulkcopy.DestinationTableName = tableName;//数据库中的表名 sqlbulkcopy.WriteToServer(source);
return;
}
}
this.CreateTable(source.Columns, tableName, primaryKeys);
var sqlBulkCopy = new System.Data.SqlClient.SqlBulkCopy(databaseConnString, SqlBulkCopyOptions.FireTriggers);//启动触发器
if (useTransaction == true)
{
sqlBulkCopy = new System.Data.SqlClient.SqlBulkCopy(databaseConnString, SqlBulkCopyOptions.UseInternalTransaction | SqlBulkCopyOptions.FireTriggers); //导入的数据在一个事务中
}
sqlBulkCopy.DestinationTableName = tableName;
foreach (DataColumn c in source.Columns)
{
sqlBulkCopy.ColumnMappings.Add(c.ColumnName, c.ColumnName);
}
//SqlBulkCopy.BulkCopyTimeout = this.timeout; //超时时间
sqlBulkCopy.BatchSize = ; //每次传输3000行
sqlBulkCopy.WriteToServer(source);
}
        /// <summary>
/// 创建表以及触发器
/// </summary>
/// <param name="columns">列名</param>
/// <param name="tableName">表名</param>
/// <param name="primaryKeys">主键的列名</param>
public void CreateTable(System.Data.DataColumnCollection columns, string tableName, string[] primaryKeys)
{
if (primaryKeys == null || primaryKeys.Length < )
{
MessageBox.Show("主键不允许为空!");
return;
}
StringBuilder sb = new StringBuilder();
// sb.Append("create table [" + tableName + "] (autoId int identity(1,1),");
sb.Append("create table [" + tableName + "] (");
foreach (DataColumn column in columns)
{
sb.Append(" [" + column.ColumnName + "] " + this.GetTableColumnType(column.DataType) + ",");
} string sql = sb.ToString();
sql = sql.TrimEnd(',');
sql += ")"; sb.Clear();
var temp1 = primaryKeys;
for (int i = ; i < primaryKeys.Length; i++)
{
temp1[i] = tableName + "." + primaryKeys[i] + "=Inserted." + primaryKeys[i];
}
List<string> temp2 = new List<string>();
for (int i = ; i < columns.Count; i++)
{
temp2.Add(columns[i].ColumnName + "=Inserted." + columns[i].ColumnName);
}
List<string> temp3 = new List<string>();
for (int i = ; i < columns.Count; i++)
{
temp3.Add(columns[i].ColumnName);
}
sb.Append("CREATE TRIGGER [tri_" + tableName + "_edit] ON [" + tableName + "] instead of insert as");
sb.Append(" IF EXISTS (");
sb.Append("SELECT * FROM " + tableName + ",Inserted WHERE " + String.Join(" AND ", temp1) + ")");
sb.Append(" UPDATE [" + tableName + "] SET " + string.Join(",", temp2) + " FROM [" + tableName + "] JOIN inserted ON " + String.Join(" AND ", temp1) + " ");
sb.Append(" ELSE "); sb.Append(" INSERT [" + tableName + "](" + string.Join(",", temp3) + ") SELECT " + string.Join(",", temp3) + " FROM inserted ");
// sql = sql + " ; " + sb.ToString();
SqlHelper.ExecuteNonQuery(SqlHelper.ConnectionString, CommandType.Text, sql);
SqlHelper.ExecuteNonQuery(SqlHelper.ConnectionString, CommandType.Text, sb.ToString());
}
       private string GetTableColumnType(System.Type type)
{
string result = "varchar(255)";
string sDbType = type.ToString();
switch (sDbType)
{
case "System.String":
break;
case "System.Int16":
result = "int";
break;
case "System.Int32":
result = "int";
break;
case "System.Int64":
result = "float";
break;
case "System.Decimal":
result = "decimal(18,4)";
break;
case "System.Double":
result = "decimal(18,4)";
break;
case "System.DateTime":
result = "datetime";
break;
default:
break;
}
return result;
}

C#使用SqlBulkCopy将DataTable写入数据库的表中(表不存在则创建新表,数据存在则更新,不存在则插入)的更多相关文章

  1. dataTable写入数据库(大数据写入)

    例1: connectionStr,链接字符串dataTableName, 数据库中对应表名sourceDataTable DataTable 要写入数据库的DataTable字段要和表一致 publ ...

  2. Oracle 数据库基础学习 (二) 学习小例子:创建一个表,记录商品买卖的情况

      运行环境:Oracle database 11g + PL/SQL Developer ex: --创建一个表 create table plspl_test_product( --加入not n ...

  3. 用c#在Access数据库中创建新表

    生成表NewTable,该表有文本字段Field1和整型字段Field2 private void CreateNewTable()  {    OleDbConnection conn = new ...

  4. 数据库SQL Server2012笔记(四)——多表查询、子查询、分页查询、用查询结果创建新表和外连接

    1.多表查询 1)笛卡尔集: select  *  from  表名1,表名2 select  *  from  表名1.表名2  where   表名1.字段名=表名2.字段名 注: 若有两张表有同 ...

  5. Excel 导入到Datatable 中,再使用常规方法写入数据库

    首先呢?要看你的电脑的office版本,我的是office 2013 .为了使用oledb程序,需要安装一个引擎.名字为AccessDatabaseEngine.exe.这里不过多介绍了哦.它的数据库 ...

  6. 《项目经验》--通过js获取前台数据向一般处理程序传递Json数据,并解析Json数据,将前台传来的Json数据写入数据库表中

      先看一下我要实现的功能界面:   这个界面的功能在图中已有展现,课程分配(教师教授哪门课程)在之前的页面中已做好.这个页面主要实现的是授课,即给老师教授的课程分配学生.此页面实现功能的步骤已在页面 ...

  7. 通过js获取前台数据向一般处理程序传递Json数据,并解析Json数据,将前台传来的Json数据写入数据库表中

    摘自:http://blog.csdn.net/mazhaojuan/article/details/8592015 通过js获取前台数据向一般处理程序传递Json数据,并解析Json数据,将前台传来 ...

  8. 如何将XML文件写入数据库

    将xml文件转成string public string XMLDocumentToString(XmlDocument doc) { MemoryStream stream = new Memory ...

  9. 【数据传输 2】批量导入的前奏:将Excel表中的数据转换为DataTable类型

    导读:我们知道,在数据库中,数据集DataSet是由多张DataTable表组成.所以,如果我们需要将数据从外部导入到数据库中,那么要做的很重要的一步是将这些数据转换为数据库可以接受的结构.今天在用S ...

随机推荐

  1. LCS最大公共子序列问题

    在生物应用中,经常需要比较两个(或多个)不同生物体的DNA, 例如:某种生物的DNA可能为S1=ACCGGTCGAGTGCGCGGAAGCCGGCCGAA, 另一种生物的DNA可能为S2=GTCGTT ...

  2. hdu 1029(hash)

    传送门:Ignatius and the Princess IV 题意:给n个数,找出出现次数大于等于(n+1)/2的那个数. 分析:大水题,排个序输出中间那个即可,这里随便写个HASHMAP找出次数 ...

  3. centos 6.3 vnc连接—— catalog is not properly configured, attempting to determine an appropriate font p

    摘要:linux环境下,利用VNC连接远程桌面是经常用到的.这里,我们介绍centos上,利用VNC连接远程桌面的方法和常见的两个问题的解决方法1)由于字体问题,导致VNCserver无法启动 2)由 ...

  4. Android笔记之网络-基本了解

    1.3个相关API接口 Android网络编程相关的API接口与相关用途例如以下图 2. 2种网络架构模式 B/S----浏览器/server端模式,通过应用层的HTTP协议通信,不须要特定clien ...

  5. WPF界面设计技巧(5)—自定义列表项呈现内容

    原文:WPF界面设计技巧(5)-自定义列表项呈现内容 接续上次的程序,稍微改动一下原有样式,并添加一个数据模板,我们就可以达成下面这样的显示功能: 鼠标悬停于文件列表项上,会在工具提示中显示图像缩略图 ...

  6. C语言sizeofkeyword

    说明: ******C语言sizeof是keyword.是一个操作符.它不是一个函数.用于计算可变.或内存数据字节数占用类型. ******sizeof有三种不同的方式: ***sizeof(变量名) ...

  7. HDU ACM 2586 How far away ?LCA-&gt;并查集+Tarjan(离线)算法

    题意:一个村子有n个房子,他们用n-1条路连接起来,每两个房子之间的距离为w.有m次询问,每次询问房子a,b之间的距离是多少. 分析:近期公共祖先问题,建一棵树,求出每一点i到树根的距离d[i],每次 ...

  8. Python3.2官方文件翻译--课堂笔记和异常是阶级

    6.7备注 有时喜欢Pasca在"录"和C中"数据体"的数据类型很实用.集合一些数据项. 一个空类定义能够清楚地显示: class Employee: pass ...

  9. 对于Web开发来说 8 个最好的跨平台编辑器

    1) Best Cross Platform IDE - Brackets Brackets是一个在前端Web开发和设计人员中最流行的开放源代码IDE/代码编辑器之中的一个.它拥有一些有用工具可以将H ...

  10. ByteBuffer的allocate和allocateDirect

    在Java中当我们要对数据进行更底层的操作时,一般是操作数据的字节(byte)形式,这时经常会用到ByteBuffer这样一个类.ByteBuffer提供了两种静态实例方式: public stati ...