SqlBulkCopy与触发器,批量插入表(存在则更新,不存在则插入)

原文:SqlBulkCopy与触发器,批量插入表(存在则更新,不存在则插入)

临时表:Test

/****** 对象:  Table [dbo].[Test]    脚本日期: 05/10/2013 11:42:07 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Test](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [UserID] [int] NOT NULL,
    [UserName] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NULL,
 CONSTRAINT [PK_Test] PRIMARY KEY CLUSTERED
(
    [ID] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

 

临时表的触发器:tri_edit

CREATE TRIGGER [tri_edit]  ON [dbo].[Test]
instead of insert
as
declare @temp int 

select @temp= inserted.UserID from inserted

--更新已经存在的主键(更新全部字段)
if(@temp IS Not NULL )

update [Test] set UserQQ=inserted.UserQQ
from [Test]  join inserted  on [Test].UserID=inserted.UserID

else --(更新指定的部分字段)

 

update [Test] set UserName=inserted.UserName
from [Test]  join inserted  on [Test].UserID=inserted.UserID

 

--插入存在的主键数据
insert [Test] (UserID,UserName)
select inserted.UserID,inserted.UserName
from inserted  left join [Test]  on inserted.UserID=[Test].UserID
where [Test].id is null

go

 

C#  SqlBulkCopy方法:

/// <summary>
        /// SqlBulkCopy往数据库中批量插入数据
        /// </summary>
        /// <param name="sourceDataTable">数据源表</param>
        /// <param name="targetTableName">服务器上目标表</param>
        /// <param name="mapping">创建新的列映射,并使用列序号引用源列和目标列的列名称。</param>
        public static void BulkToDB(DataTable sourceDataTable, string targetTableName, SqlBulkCopyColumnMapping[] mapping)
        {
            /*  调用方法 - 2013年05月10日编写
            //DataTable dt = Get_All_RoomState_ByHID();
            //SqlBulkCopyColumnMapping[] mapping = new SqlBulkCopyColumnMapping[4];
            //mapping[0] = new SqlBulkCopyColumnMapping("Xing_H_ID", "Xing_H_ID");
            //mapping[1] = new SqlBulkCopyColumnMapping("H_Name", "H_Name");
            //mapping[2] = new SqlBulkCopyColumnMapping("H_sName", "H_sName");
            //mapping[3] = new SqlBulkCopyColumnMapping("H_eName", "H_eName");
            //BulkToDB(dt, "Bak_Tts_Hotel_Name", mapping);
            */

             using (SqlConnection conn = new SqlConnection(DBHelper.ConnectionString))
            {
                //SqlBulkCopy bulkCopy = new SqlBulkCopy(conn);   //用其它源的数据有效批量加载sql server表中
                //指定大容量插入是否对表激发触发器。此属性的默认值为 False。
                SqlBulkCopy bulkCopy = new SqlBulkCopy(DBHelper.ConnectionString, SqlBulkCopyOptions.FireTriggers);
                bulkCopy.DestinationTableName = targetTableName;    //服务器上目标表的名称
                bulkCopy.BatchSize = sourceDataTable.Rows.Count;   //每一批次中的行数
                //bulkCopy.BulkCopyTimeout = 300; //超时之前操作完成所允许的秒数,大批量数量需要的时长5分钟,2013-11-6备注 报错:“超时时间已到。在操作完成之前超时时间已过或服务器未响应”  解决办法:   

          
                if (sourceDataTable != null && sourceDataTable.Rows.Count != 0)
                {
                    for (int i = 0; i < mapping.Length; i++)
                        bulkCopy.ColumnMappings.Add(mapping[i]);


                    //将提供的数据源中的所有行复制到目标表中
                    bulkCopy.WriteToServer(sourceDataTable);
                }
            }


C# 调用BulkToDB方法:

int kk = Environment.TickCount;
            DataTable dt = new DataTable();
            dt.Columns.Add(new DataColumn("UserID", typeof(string)));
            dt.Columns.Add(new DataColumn("UserName", typeof(string)));
            for (int k = 0; k < 10000; k++) //40000
            {
                DataRow dr = dt.NewRow();
                dr["UserID"] = k;
                dr["UserName"] = "8888 - " + k;
                dt.Rows.Add(dr);
            }
            SqlBulkCopyColumnMapping[] mapp = new SqlBulkCopyColumnMapping[2];
            mapp[0] = new SqlBulkCopyColumnMapping("UserID", "UserID");
            mapp[1] = new SqlBulkCopyColumnMapping("UserName", "UserName");
            //提交任务表
            BulkToDB(dt, "Test", mapp);
            int exeg = Environment.TickCount - kk;
            MessageBox.Show(exeg.ToString());

                  

动态加载数据列名:

 SqlBulkCopyColumnMapping[] mapp = new SqlBulkCopyColumnMapping[dt.Columns.Count];
                    for (int j = 0; j < dt.Columns.Count; j++)
                    {
                        mapp[j] = new SqlBulkCopyColumnMapping(dt.Columns[j].ColumnName, dt.Columns[j].ColumnName);
                    }

 

1、--处理的触发器示例
create trigger tr_insert on 表
instead of insert  --注意触发器的类型
as
--更新已经存在的主键
update 表 set name=b.name,sex=b.sex
from 表 a join inserted b on a.id=b.id

--插入存在的主键数据
insert 表
select a.*
from inserted a left join 表 b on a.id=b.id
where b.id is null
go
——————————————————————————————————————————

2、--触发器
CREATE TRIGGER tri_edit  ON tab
INSTEAD OF INSERT
AS

if exists(select col1,col2 from tab join inserted on tab.学号=INSERTED.学号)
 begin
--这里面你可以加如些其他修改操作,取决于具体的功能
        update tab set col1='num1' from tab join inserted on tab.学号=inserted.学号
 end
else
 insert tab  select * from inserted
GO

 

                

时间: 2024-12-31 13:16:45

SqlBulkCopy与触发器,批量插入表(存在则更新,不存在则插入)的相关文章

SQL Server 利用触发器对多表视图进行更新的实现方法_MsSql

其步骤就是:利用update操作触发器产生的2个虚拟表[inserted]用来存储修改的数据信息和[deleted]表,然后将对应的数据更新到对应数据表中的字段信息中: 1.首先创建3个表: a.信息表: USE [SQL-LI] BEGIN TRANSACTION CHUANGJIAN_XINXIN_TAB --创建命名为[XINXIN_TAB]的数据表,同时不允许字段为空 CREATE TABLE XINXIN_TAB ( 姓名 NVARCHAR(10) NOT NULL, 性别 NVARC

SQL Server 利用触发器对多表视图进行更新的实现方法

其步骤就是:利用update操作触发器产生的2个虚拟表[inserted]用来存储修改的数据信息和[deleted]表,然后将对应的数据更新到对应数据表中的字段信息中: 1.首先创建3个表: a.信息表: USE [SQL-LI] BEGIN TRANSACTION CHUANGJIAN_XINXIN_TAB --创建命名为[XINXIN_TAB]的数据表,同时不允许字段为空 CREATE TABLE XINXIN_TAB ( 姓名 NVARCHAR(10) NOT NULL, 性别 NVARC

SQL Server 利用触发器对多表视图进行更新

原文 http://www.cnblogs.com/liyifeng/archive/2013/05/05/3056968.html 其步骤就是:利用update操作触发器产生的2个虚拟表[inserted]用来存储修改的数据信息和[deleted]表,然后将对应的数据更新到对应数据表中的字段信息中: 1.首先创建3个表: a.信息表: 1 USE [SQL-LI] 2 BEGIN TRANSACTION CHUANGJIAN_XINXIN_TAB 3 --创建命名为[XINXIN_TAB]的数

c#实现批量插入数据到sql数据库表中,怎么做到跳过插入失败的数据,继续插入

问题描述 c#实现批量插入数据到sql数据库表中,怎么做到跳过插入失败的数据,继续插入 c#实现批量插入数据到sql数据库表中,怎么做到跳过插入失败的数据,继续插入. 并且报错,哪几天数据失败了.和失败的原因. 我现在是可以生成一个把一个数据库表的数据导入到另一个数据库表中.但是呢,有些数据由于某个字段过长无法导入成功,而导致所有的都无法导入.直接造成导入失败.我 想过滤掉那条不成功的继续导入.不至于都导入不成功.急! 想和好久也没解决.网上也没找到说法 解决方案 数据库表插入数据失败数据库批量

批量将数据表中原有的数据稍微变更再插入本表中

问题描述 批量将数据表中原有的数据稍微变更再插入本表中 表A中有以下字段,A_id,A_user_id,A_func_code,现在表A中有以下数据 A_id A_user_id A_func_code 1 张三 111 2 张三 222 3 张三 333 现在要表A中再插入数据,数据要求 要求为A_user_id等于张三的再插入时张三变更为李四 A_id为 sequence,大致描述如此,实际数据中不止这几个字段,数据也不止三条 等于说就是把原表中的A_user_id的数据再插入到本表中,只是

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

原文:.net使用SqlBulkCopy导入数据(创建新表) .net2.0后ado.net提供了一个快速导入sqlserver的方法sqlbulkcopy.导入效率非常高.  包装了一个简单的sqlbulkcopy类,用于数据从datatable导入到sqlserver.代码如下:   /// <summary> /// 将DataTable写入数据库的表中 /// </summary> /// <param name="source">数据源Da

SQL 触发器批量删除数据

问题描述 SQL 触发器批量删除数据 有A主表,B表为临时表两个表,两个表的结构完全相同,主键分别为ch_billno,ch_tableno,ssid,我想做一个触发器,当A表插入主键数据时,把临时表中存在相同主键的数据删除,插入数据的时候会用到sqlbulkcopy方式插入,只会引发一次insert操作. 解决方案 亲测可用, 楼主速速采纳吧, 呵呵 --1. 创建测试表 A,B 及测试数据 IF OBJECT_ID('dbo.A') IS NOT nuLL BEGIN DROP TABLE

用触发器生成数据库表的数据操作日志

作为一名数据库管理员,你尽力以各部门熟知的不同格式,向各部门提供它们所需要的数据.你通常将MS Excel格式的数据递交到会计部门,或将数据以HTML报表的形式呈现给普通用户.你们的系统安全管理员们则习惯于用文本阅读器或者事件查看器来查看日志.本文将介绍如何使用触发器,把DML(数据操作语言)对数据库中的特定数据表的改动记录下来.注:下列例子为Insert型触发器,不过改成Delete/Update型的触发器也很容易. 操作步骤首先让我们在Northwind数据库内创建一个简单表. create

Oracle触发器不能读取表的问题

问题描述 Oracle触发器不能读取表的问题 12.假设有这样一张用户表表结构如下:UserInfo(id ,username,userPass),希望向表中增加数据时,表中id列的数字自动生成.(选做) 1)第一步创建序列,要求开始的数字为1,每次递增1,按顺序产生序列值: 2)第二步创建一个触发器,向用户表中插入数据的时候触发触发器,在触发器内部调用序列并生成一个序列值赋值给表的id列. 触发器: create or replace trigger pro_id after insert o