关于触发器在数据批量更新或批量插入时为什么只有最后一条数据能触发更新?

想到才能做到 2012-06-08 01:51:39
今天在skyzero110的博客看了如何实现拼音码的查询,于是着手测试“当商品表的商品名称被更新时触发更新商品表的拼音码字段为改后的商品名称的拼音码”。

经测试用以下过程我触发器如果更新记录只有一条时触发生成的拼音码正确,但如果执行"update spbm set spmc=123"时,由于SPBM表的记录不止一条就会出现只能更新到最后一条记录的拼音码,其它记录都没有触发更新!

哪位老师能教教我如何实现能批量生成和更新拼音码的方法吗?

以下为现在用到的过程我触发器:

--存储过程 将汉字转化成拼音输出
create proc Hz2Py
@hz varchar(200),
@py varchar(200) output
AS
declare @i int
declare @chr varchar(2)
declare @pyc varchar(1)
set @i=1
while (@i<=len(@hz)) begin
set @chr=substring(@hz,@i,1)
set @pyc=(select py from pycode where hz=@chr)
if(@pyc is null)
set @py=@py+@chr
else
set @py=@py+@pyc
Set @i=@i+1
end

--触发器 当插入,更新时 更改拼音码
create trigger pybm on spbm for insert,update
AS
declare @name varchar(100),@npy varchar(100),@cid char(11)

if(update(spmc)) begin
set @npy=''
select @name=spmc,@cid=spbm from inserted
exec Hz2Py @name,@npy output

update spbm set pybm=@npy where spbm=@cid

end
GO
...全文
723 9 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
lycorisraya 2012-06-08
  • 打赏
  • 举报
回复
update spbm set pybm=@npy where spbm=@cid

问题应该出在这里了,不管你插入或者更新多少条记录,但触发器激发的时候,update语句就只更新了spbm等于当前@cid的那条记录,而当前@cid的值刚好等于存储过程中while循环的最后一个值,你这条语句本质上是只更新一条记录。
想到才能做到 2012-06-08
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]

SQL code
create trigger pybm on spbm for insert,update
AS
declare @name varchar(100),@npy varchar(100),@cid char(11)

if(update(spmc)) begin
DECLARE cur_rec CURSOR LOCAL SCROLL FOR
select spmc,spb……
[/Quote]

谢谢你的帮助,还想问一个关于速度的问题。用你以上触发器的话批量更新的记录一千条所用的时间需要50秒左右.
有没有更快一点的方法?
想到才能做到 2012-06-08
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]

try this,
SQL code

create trigger pybm on spbm
for insert,update
AS
declare @name varchar(100),@npy varchar(100),@cid char(11)

if(update(spmc))
begin
declare spmclist cursor forward_only
……
[/Quote]

谢谢你的帮助,还想问一个关于速度的问题。用你以上触发器的话批量更新的记录一千条所用的时间需要20-30秒.
有没有更快一点的方法?
想到才能做到 2012-06-08
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]

UPDATE的话,多条inserted里面有多条数据,你通过表变量存一下一条条执行就可以了。
大体改一下,你试试吧。
SQL code

create trigger pybm on spbm for insert,update
AS
declare @name varchar(100),@npy varchar(100),@cid char(11)
DECLARE @Table TABL……
[/Quote]

执行你的语句时提示如下:
消息 139,级别 15,状态 1,过程 pybm,第 6 行
不能向局部变量赋予默认值。
消息 137,级别 15,状态 2,过程 pybm,第 15 行
必须声明变量 '@Line'。
消息 137,级别 15,状态 2,过程 pybm,第 19 行
必须声明变量 '@Line'。
消息 137,级别 15,状态 2,过程 pybm,第 26 行
必须声明变量 '@Line'。
唐诗三百首 2012-06-08
  • 打赏
  • 举报
回复
try this,

create trigger pybm on spbm
for insert,update
AS
declare @name varchar(100),@npy varchar(100),@cid char(11)

if(update(spmc))
begin
declare spmclist cursor forward_only
for select spmc,spbm from inserted

open spmclist
fetch next from spmclist into @name,@cid
while(@@fetch_status<>-1)
begin
set @npy=''
exec Hz2Py @name,@npy output
update spbm set pybm=@npy where spbm=@cid
fetch next from spmclist into @name,@cid
end
close spmclist
deallocate spmclist
end
GO
codehole 2012-06-08
  • 打赏
  • 举报
回复
我是这样看的

上面说的都很清楚了

你这个触发器只适合于一条信息

create trigger pybm on spbm for insert,update
AS
declare @name varchar(100),@npy varchar(100),@cid char(11)
SELECT COUNT(1) FROM inserted --你看以看看这里的是多少记录
if(update(spmc)) begin
set @npy=''
select @name=spmc,@cid=spbm from inserted --如果是多条记录,你这里只能取到最后一条,因为前面的都被你覆盖了。
exec Hz2Py @name,@npy output

update spbm set pybm=@npy where spbm=@cid

end
GO
xuam 2012-06-08
  • 打赏
  • 举报
回复
create trigger pybm on spbm for insert,update
AS
declare @name varchar(100),@npy varchar(100),@cid char(11)

if(update(spmc)) begin
DECLARE cur_rec CURSOR LOCAL SCROLL FOR
select spmc,spbm from inserted
OPEN cur_rec
FETCH NEXT FROM cur_rec INTO @name,@cid
WHILE (@@fetch_status <> -1)
BEGIN
set @npy=''
exec Hz2Py @name,@npy output
update spbm set pybm=@npy where spbm=@cid
FETCH NEXT FROM cur_rec INTO @name,@cid
END

CLOSE cur_rec
DEALLOCATE cur_rec


end
GO
--小F-- 2012-06-08
  • 打赏
  • 举报
回复
 --try
update a set pybm=@npy from spbm a join inserted i on a.spmc=i.spmc and spbm=@cid
孤独加百列 2012-06-08
  • 打赏
  • 举报
回复
UPDATE的话,多条inserted里面有多条数据,你通过表变量存一下一条条执行就可以了。
大体改一下,你试试吧。

create trigger pybm on spbm for insert,update
AS
declare @name varchar(100),@npy varchar(100),@cid char(11)
DECLARE @Table TABLE(ID INT IDENTITY(1,1),name VARCHAR(100),cid INT)
DECLARE @Total INT
DECLARE @Line INT = 1

if(update(spmc)) begin
set @npy=''
INSERT INTO @Table
select spmc,spbm from inserted

SELECT @Total = MAX(ID) FROM @Table

WHILE @Line <= @Total
BEGIN


select @name=name,@cid=cid from @Table WHERE ID = @Line

exec Hz2Py @name,@npy output

update spbm set pybm=@npy where spbm=@cid


SET @Line = @Line + 1

END


end
GO

27,582

社区成员

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

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