`
guoxinzz
  • 浏览: 431220 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

[转]lBulkCopy与Insert触发器的应用问题

 
阅读更多

sqlBulkCopy是.net2.0提供的一个快速批量插入数据的新对象。

出于这个对象主要作为作为了提高批量插入的效率,所以在默认情况下批量数据的插入并不会引发insert触发器的触发。但在有些情况下必须要用到这个触发器,这可以通过使用SqlBulkCopy (String, SqlBulkCopyOptions) 指定enum SqlBulkCopyOptions为FireTriggers解决。

在项目中有一个记账功能,每一条记录的结余数要从上一次的结余数与本次账的增减计算后得出。原来的写法是由前端对账的每一条依次插入新的记录,并利用insert触发器计算结余数。insert触发器写法如下:

select a.ParentID,max(a.Stamp) stamp into #temp1

from ivInventoryItem a, inserted b

where a.ParentId = b.ParentID and a.OID b.OID

group by a.ParentID

select @lastCurrentQty1 = isnull( t.CurrentQty1, 0) , @lastCurrentQty2 = isnull( t.CurrentQty2, 0),

@lastCurrentQty3 = isnull( t.CurrentQty3, 0) , @lastCurrentQty4 = isnull( t.CurrentQty4, 0)

from ivInventoryItem t

inner join #temp1 iv on t.ParentID = iv.ParentID and t.Stamp = iv.stamp

drop table #temp1

--现存数 = 上次现存数 + 收入数 - 支出数

update ivInventoryItem set CurrentQty1 = @lastCurrentQty1 + isnull( inserted.DepositQty1,0) - isnull(inserted.WithdrawalQty1, 0),

CurrentQty2 = @lastCurrentQty2 + isnull( inserted.DepositQty2,0) - isnull(inserted.WithdrawalQty2, 0),

CurrentQty3 = @lastCurrentQty3 + isnull( inserted.DepositQty3,0) - isnull(inserted.WithdrawalQty3, 0),

CurrentQty4 = @lastCurrentQty4 + isnull( inserted.DepositQty4,0) - isnull(inserted.WithdrawalQty4, 0)

from inserted where ivInventoryItem.OID = inserted.OID

*/

--现存数 = 上次现存数 + 收入数 - 支出数

update ivInventoryItem set CurrentQty1 = @lastCurrentQty1 + isnull( inserted.DepositQty1,0) - isnull(inserted.WithdrawalQty1, 0),

CurrentQty2 = @lastCurrentQty2 + isnull( inserted.DepositQty2,0) - isnull(inserted.WithdrawalQty2, 0),

CurrentQty3 = @lastCurrentQty3 + isnull( inserted.DepositQty3,0) - isnull(inserted.WithdrawalQty3, 0),

CurrentQty4 = @lastCurrentQty4 + isnull( inserted.DepositQty4,0) - isnull(inserted.WithdrawalQty4, 0)

from inserted where ivInventoryItem.OID = inserted.OID

由于系统是一个大量数量业务处理系统,当每一次记账数量较多时(>2000),此方法的性能明显出现问题。于是前端改为SqlBulkcopy,这样性能明显提高很多。但发现insert触发器不工作。原来SqlBulkcopy对象主要作为作为了提高批量插入的效率,所以在默认情况下批量数据的插入并不会引发insert触发器的触发。这可以通过使用SqlBulkCopy (String, SqlBulkCopyOptions) 指定enum SqlBulkCopyOptions为FireTriggers解决。但触发器工作后综合结余数的计算并不正确。分析上面的触发器,发现它利用了inserted临时表中的记录获取本次插入记录的上一次记录的结余。但现在由于使用SqlBulkcopy,一次插入多条记录,就不能在每次触发中从inserted中查出一条记录。实际上在一个插入或更新事务处理中,新建行被同时添加到 inserted 表和触发器表中,所以,使用SqlBulkcopy时在inserted表中是有多条记录的,且一次调用SqlBulkcopy只会有一次触发器的运行。

更改触发器如下,测试数量正常:

select a.ParentId,max(a.Stamp) stamp into #temp1

from ivInventoryItem a, inserted b

where a.ParentId = b.ParentID and a.OID b.OID

group by a.ParentId

--现存数 = 上次现存数 + 收入数 - 支出数

update ivInventoryItem set

CurrentQty1 = isnull(p.CurrentQty1,0) + isnull( i.DepositQty1,0) - isnull(i.WithdrawalQty1, 0) ,

CurrentQty2 = isnull(p.CurrentQty2,0) + isnull( i.DepositQty2,0) - isnull(i.WithdrawalQty2, 0) ,

CurrentQty3 = isnull(p.CurrentQty3,0)+ isnull( i.DepositQty3,0) - isnull(i.WithdrawalQty3, 0) ,

CurrentQty4 = isnull(p.CurrentQty4,0)+ isnull( i.DepositQty4,0) - isnull(i.WithdrawalQty4, 0)

from ivInventoryItem c,(select * from ivInventoryItem) p, #temp1 t ,inserted i

where p.ParentID = t.ParentID and p.Stamp = t.stamp and t.ParentID = i.ParentID

and c.oid = i.oid and (isnull( i.CurrentQty1, 0 ) + isnull( i.CurrentQty2, 0 ) + isnull( i.CurrentQty3, 0 ) + isnull( i.CurrentQty4, 0 ) =0)

drop table #temp1

分享到:
评论

相关推荐

    C#中的Insert触发器应用实例源代码

    摘要:C#源码,数据库应用,Insert,触发器 C#中的Insert触发器应用实例源代码,触发器的例子,免费下载C#源码。

    触发器---FOR INSERT与INSTEAD OF

    触发器---FOR INSERT与INSTEAD OF ,SQL中触发器的讲述,可以利用触发器来处理数据库相关程序

    sqlserver 触发器 insert阿

    sqlserver 触发器 insert阿 一个关于触发器的小例子

    对有insert触发器表取IDENTITY值时发现的问题

    问题是这样的: T1表上有一个INSERT的触发器,在插入数据的时候,会自动往T2表里面插一条记录 这样当我在T1表上插入新的数据时,取@@IDENTITY的时候,返回的id值是T2表里面的新记录的值 赶快查了下msdn,原来@@IDENTITY...

    insert创建添加类型的触发器

    创建添加的触发器,可以帮助你创建添加类型的触发器,轻松的再数据库端控制,

    SQL Server数据库中使用触发器经验谈

    触发器是数据库应用中的重用工具,它的应用很广泛。当触发INSERT触发器时,新的数据行就会被插入到触发器表和inserted表中。inserted表是一个逻辑表,它包含了已经插入的数据行的一个副本。inserted 表包含了INSERT...

    触发器的工作过程

    可以定义一个无论何时用INSERT语句向表中插入数据时都会执行的触发器。 当触发INSERT触发器时,新的数据行就会被插入到触发器表和inserted表中。inserted表是一个逻辑表,它包含了已经插入的数据行的一个副本。...

    数据库存储过程与触发器

    假定有学校的图书馆管理信息系统,可以用于日常管理书库和同学们的借还书工作。以下列出参考的库表情况: 根据管理的业务需求来分析,该管理信息系统的数据库应至少包括如下数据表(你也可以根据需要,自行添加所需...

    SQLServer触发器实现不同服务器数据同步.pdf

    SQLServer触发器实现不同服务器数据同步.pdf

    数据库触发器

    可以定义一个无论何时用INSERT语句向表中插入数据时都会执行的触发器。 当触发INSERT触发器时,新的数据行就会被插入到触发器表和inserted表中。inserted表是一个逻辑表,它包含了已经插入的数据行的一个副本。...

    SQL Server数据库实验_存储过程与触发器设计.docx

    掌握触发器的定义及应用。 二、实验原理 1、 使用CREATE TRIGGER语句定义触发器,ALTER TRIGGER语句修改触发器,DROP TRIGGER语句删除触发器。 2、 触发器分AFTER/FOR和INSTEAD OF两种类型:AFTER/FOR类型的触发器是...

    sql各类触发器代码

    SQL:UPDATE、DELETE、INSERT触发器

    sqlserver触发器例子

    如果一个Insert﹑update或者delete语句违反了约束﹐那幺After触发器不会执行﹐因为对约束的检查是在After触发器被激动之前发生的。所以After触发器不能超越约束。 Instead of 触发器可以取代激发它的操作来执行...

    实验4答案-触发器.sql

    为LoanT表创建一个INSERT语句级触发器,当有新的贷款记录插入时,需要及时更新LoanNum表中该法人的贷款次数。 2、创建一个AFTER行级触发器,当对LoanT表的贷款金额(Lamount)进行修改时,若金额减少了10%,则将...

    sql 触发器 详解与实例

    诸如:update、insert、delete这些操作的时候,系统会自动调用执行该表上对应的触发器。SQL Server 2005中触发器可以分为两类:DML触发器和DDL触发器,其中DDL触发器它们会影响多种数据定义语言语句而激发,这些语句...

    sqlserver 触发器学习(实现自动编号)

    总结常用基本点如下: 1、触发器有两种... 2、DML触发器分类:Insert触发器、Delete触发器、Update触发器、上面任意类型混合。 3、触发器创建语法: 代码如下: CREATE TRIGGER <trigger> ON <table> {{{FOR|AFTER} <

    SQL触发器使用实例

    创建触发器[T_INSERT_卷烟库存表],这个触发器较简单。 说明: 每当[卷烟库存表]发生 INSERT 动作,则引发该触发器。 触发器功能: 强制执行业务规则,保证插入的数据中,库存金额 = 库存数量 * 库存单价。 注意: ...

    trigger触发器trigger触发器trigger触发器

    --行级触发器 create or replace trigger insert_person after insert on person for each row begin insert into person2 values(:new.id,:new.name,:new.password); end; create or replace trigger update_...

    数据库技术与应用 insert语句名称解析与常见问题.doc

    数据库技术与应用 insert语句名称解析与常见问题.doc 学习资料 复习资料 教学资源

Global site tag (gtag.js) - Google Analytics