请教一个触发器的问题?

jcdwin3 2004-08-16 04:41:41
我写了一个触发器是这样写的
create trigger add on table1
for insert

declare @ffkh int ,@ffje smallint @fflx smallint

select @ffje=ck_ffje,@ffkh=ck_ffkh ,@fflx=fflx from inserted

if @fflx=1
begin

update tf_yfk set yf_ye=yf_ye-ffje where yf_kh=@ffkh

end
如果用dts导入多条到table1的话,这个触发器只能触发一条,怎样改才能触发多条呢?是不是因为有if @fflx=1 的原因?如果修改可以不可以改为:
create trigger add on table1
for insert

declare @ffkh int ,@ffje smallint @fflx smallint

select @ffje=ck_ffje,@ffkh=ck_ffkh ,@fflx=fflx from inserted where fflx=1


begin

update tf_yfk set yf_ye=yf_ye-ffje where yf_kh=@ffkh

end
...全文
135 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
jcdwin3 2004-08-16
  • 打赏
  • 举报
回复
非常感谢,我先回去测试一下,如果成功,一定开贴送分与大家
CSDMN 2004-08-16
  • 打赏
  • 举报
回复
典型的丢失处理的错误

zjcxc 2004-08-16
  • 打赏
  • 举报
回复
--SQL的触发器不是行级触发,所以无论你插入多少条记录,都只触发一次
--而用变量来处理的话,实际只处理了最后一条插入的记录,因为变量只能得到一条记录的值

--建议触发器修改如下

create trigger [add] on table1 --触发器名有问题
for insert
as --少了as
if exists(select 1 from inserted where fflx=1)
update a set yf_ye=a.yf_ye-b.ffje
from tf_yfk a,inserted
where a.yf_kh=b.ck_ffkh
and b.fflx=1
jcdwin3 2004-08-16
  • 打赏
  • 举报
回复
是不是有了
if @fflx=1
这样的语句,触发器就只能一条插入才有效,而象dts这样一次导入许多数据,就只能触发第一条?
了缘 2004-08-16
  • 打赏
  • 举报
回复
up
solidpanther 2004-08-16
  • 打赏
  • 举报
回复
dts 可不是1条1条插入的,是1000条为一组好象
solidpanther 2004-08-16
  • 打赏
  • 举报
回复
请看帮助里关于多行的考虑事项,其中 “C. 存储基于插入类型的运行总计”为解决方案,仔细看
在写触发器代码时需要考虑的一个重要问题就是,引发触发器的语句可以是一个影响多行的单一语句,而不仅是影响一行。这在 UPDATE 和 DELETE 触发器中很常见,因为这些语句经常作用于多行。而这在 INSERT 触发器中就比较少见,因为基本的 INSERT 语句只添加一行。然而,由于 INSERT 触发器可由 INSERT INTO (table_name) SELECT 语句激发,所以插入许多行可能导致单个的触发器调用。

在下列情况下关于多行的考虑尤为重要:触发器的功能是自动重新计算表中的汇总值,并将结果存储在另一个正在进行的计数中。



说明 由于存在对性能的潜在负面影响,不推荐在触发器中使用游标。使用基于行集的逻辑而非游标来设计影响多行的触发器。


示例
下例中触发器的目的是在另一个表中存储某列的运行总计。

A. 存储单行插入的运行总计
第一种触发器在一行数据装载入 sales 表中时能很好地进行单行插入。INSERT 语句激发触发器,新行在触发器执行期间装载在 inserted 表中。UPDATE 语句读取该行的 qty 列值,并将其添加到 titles 表的 ytd_sales 列中已有的值上。WHERE 子句则确保已在 sales 表中更新的行与 inserted 表中行的 title_id 相匹配。

-- Trigger is valid for single-row inserts.
CREATE TRIGGER intrig
ON sales
AFTER INSERT AS

UPDATE titles
SET ytd_sales = ytd_sales + qty
FROM inserted
WHERE titles.title_id = inserted.title_id

B. 存储多行或单行插入的运行总计
如果要进行多行插入,示例 A 中的触发器可能就不会正确工作;位于 UPDATE 语句 (ytd_sales + qty) 中赋值表达式右边的表达式只能是一个值,而不能是一个值列表。因此该触发器的作用就是获取 inserted 表中任意一行的值,并将其添加到 titles 表中特定 title_id 值的已有 ytd_sales 值上。如果某个 title_id 值在 inserted 表中出现了多次,则可能无法得到预期的效果。

为了正确地更新 titles 表,触发器就必须适应 inserted 表中出现多行的可能性。这可以通过 SUM 函数实现,它为 inserted 表中每个 title_id 计算一组行的总计 qty。SUM 函数存放于相关子查询中(SELECT 语句在括号内)。该子查询为 inserted 表中与 titles 表的 title_id 匹配或相关的每个 title_id 返回一个单一值。

-- Trigger is valid for multirow and single-row inserts.
CREATE TRIGGER intrig
ON sales
AFTER INSERT AS

UPDATE titles
SET ytd_sales = ytd_sales +
(SELECT SUM(qty) -- Correlated subquery.
FROM inserted
WHERE titles.title_id = inserted.title_id)
WHERE titles.title_id IN
(SELECT title_id FROM inserted)

该触发器对单行插入同样适用;qty 值列的总计为单行的总计。不过,使用该触发器时,WHERE 子句中所使用的相关子查询和 IN 运算符需要 Microsoft® SQL Server™ 2000 的额外处理,而这对于单行插入来说是不必的。

C. 存储基于插入类型的运行总计
可以更改触发器以针对不同行数使用最优方法。例如,可以在触发器逻辑中使用 @@ROWCOUNT 函数以区分单行插入和多行插入。

-- Trigger valid for multirow and single row inserts
-- and optimal for single row inserts.
CREATE TRIGGER intrig
ON sales
FOR INSERT AS
IF @@ROWCOUNT = 1
BEGIN
UPDATE titles
SET ytd_sales = ytd_sales + qty
FROM inserted
WHERE titles.title_id = inserted.title_id
END
ELSE
BEGIN
UPDATE titles
SET ytd_sales = ytd_sales +
(SELECT SUM(qty)
FROM inserted
WHERE titles.title_id = inserted.title_id)
WHERE titles.title_id IN
(SELECT title_id FROM inserted)
END

viptiger 2004-08-16
  • 打赏
  • 举报
回复
可以这样改啊

没太明白
victorycyz 2004-08-16
  • 打赏
  • 举报
回复
create trigger add on table1
for insert

as

begin

update tf_yfk set yf_ye=yf_ye-ffje from tf_yfk a join inserted b on a.yf_kh=b.ffkh where b.fflx=1

end

27,579

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 应用实例
社区管理员
  • 应用实例社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧