难题:触发器中使用游标,对另外一个库中表更新无效!在线等

wooden954 2009-12-24 09:36:10
我在一个数据库表中创建了一个触发器,在这个触发器中使用了游标,读取了插入或更新的数据值,根据值的内容选择更新过程,但在调试中发现更新过程无效。

SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO


--根据数据地址确定数据所在数据块首地址
ALTER TRIGGER UpdateCommandInterface ON dbo.CommandHistoryDown
FOR INSERT,Update
AS
begin
declare
@DownRecID bigint,
@BeginTime DateTime, --开始时间
@EndTime DateTime, --结束时间
@CBQ_LogicAddr bigint, --抄表器逻辑地址
@CBQID smallint,
@CBQTypeID bigint,
@TPTypeID tinyint, --
@LAddr_Start varchar(8), --
@LAddr_Start_DA varchar(8),

@CBQIO_Addr tinyint,
@CBQ_TypeID tinyint,

@IsWrite tinyint,
@L_PDU_Reply tinyint,
@IsError tinyint
declare --数据字典类型
@TermType int,
@TpType int,
@AppInterface int,
@DataName varchar(50)
declare
@InterfaceID bigint,
@CreateTime DateTime,
@CommandType Varchar(50),
@CommandPara varchar(50)
declare
@DataCellTypeID bigint
declare
@AppInterfaceName varchar(20)
--打开游标,用于读取本次插入或更新的记录数据
declare CursorDownRec cursor for
--查询“有返回数据、无错误、读取数据命令”的插入记录
Select ID,BeginTime,EndTime,CBQ_LogicAddr,TpTypeID,LAddr_Start,CBQIO_Addr,IsWrite, L_PDU_Reply,IsError
from Inserted
Open CursorDownRec
--读取记录到变量,内容有:时间,抄表器逻辑编号(非地址),读/写,数据块开始地址,是否有返回数据,是否有错误,
fetch next from CursorDownRec into
@DownRecID,@BeginTime,@EndTime,@CBQ_LogicAddr,@TpTypeID,@LAddr_Start,@CBQIO_Addr,@IsWrite,@L_PDU_Reply,@IsError
while @@fetch_status = 0
begin
--得到抄表器类型
set @CBQ_TypeID=0
Set @CBQID=0
Select top 1 @CBQID=CBQ_ID,@CBQTypeID=CBQ_TypeID from Account_CBQ where CBQ_LogicAddr=@CBQ_LogicAddr

--得到数据块首地址
set @LAddr_Start_DA = ''
SELECT top 1 @LAddr_Start_DA = LAddr_Start FROM VIEW_MemAddr_Order WHERE ( CBQ_TypeID = @CBQ_TypeID ) AND ( TPTypeID = @TPTypeID ) AND ( CBQIO_Addr = @CBQIO_Addr ) AND ( (dbo. hexnum(@LAddr_Start) between dbo.hexnum(LAddr_Start) and dbo.hexnum(LAddr_End) ) or dbo.hexnum(@LAddr_Start) = dbo.hexnum(LAddr_Start) )

--更新数数据块首地址
if @LAddr_Start_DA<>''
UPDATE CommandHistoryDown SET LAddr_Start_DA = @LAddr_Start_DA WHERE ID = @DownRecID

if @IsWrite=0 and @L_PDU_Reply>0 and @IsError=0
begin
--查询提交的数据类别和下行命令接口编号
Set @DataCellTypeID=0
Set @AppInterface=0
Set @DataName=''
select top 1 @DataCellTypeID=DC_TypeID,@AppInterface=CommandInterfaceId,@DataName=DataName
from VIEW_MemAddr_AppMasterInterface
where CBQ_TypeID=@CBQTypeID and TPTypeID=@TPTypeID and LAddr_Start=@LAddr_Start

--查询下行命令接口名称
set @AppInterfaceName=''
Select @AppInterfaceName=CommandInterfaceName from CommandInterfaceTb where CommandInterfaceID=@AppInterface
--------------------------------------------------------------------------------------
if @AppInterface=1 --月冻结表底
begin
--分析数据
if RTrim(@DataName)='上上月表底'
begin
update [scyd].[dbo].[Comm_CommandInterface] set Status='补抄成功'
where TerminalID=@CBQID
and Datepart(mm,cast(OccurDT as DateTime))=DatePart(mm,GetDate())
and TakeAwayFlag<>0
and CommandType=@AppInterfaceName
end
else if RTrim(@DataName)='上月表底'
begin
update [scyd].[dbo].[Comm_CommandInterface] set Status='补抄成功'
where TerminalID=@CBQID
and Datepart(mm,cast(OccurDT as DateTime))=DatePart(mm,GetDate())
and TakeAwayFlag<>0
and CommandType=@AppInterfaceName
end
end
--------------------------------------------------------------------------------------
else if @AppInterface=3 --瞬时表底
begin
--直接更新本装置的全部读取“瞬时表底”的数据状态为“已读取”
update [scyd].[dbo].[Comm_CommandInterface] set Status='补抄成功'
where TerminalID=@CBQID and TakeAwayFlag<>0 and CommandType=@AppInterfaceName
end
end
--读取记录到变量,内容有:时间,抄表器逻辑编号(非地址),读/写,数据块开始地址,是否有返回数据,是否有错误,
fetch next from CursorDownRec into
@DownRecID,@BeginTime,@EndTime,@CBQ_LogicAddr,@TpTypeID,@LAddr_Start,@CBQIO_Addr,@IsWrite,@L_PDU_Reply,@IsError
end
--关闭本次插入或更新记录用的游标
close CursorDownRec
deallocate CursorDownRec
end

GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO


以执行“else if @AppInterface=3 --瞬时表底”为例,
我调试过程中发现各参数取值是正确的,将调试过程的各条件写到查询分析器中执行,更新结果是正确的。
但是就是在触发器中不工作。

我一开始以为在触发器中不能进行跨库进行表更新,从网上查了些资料,发现在触发器中直接更新其它数据库的表是没有问题的,我测试是成功的。但我试验用的跨库更新代码没使用游标,是游标的问题吗?

在线等各位大大的答案。
...全文
128 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
wooden954 2009-12-25
  • 打赏
  • 举报
回复

else if @AppInterface=3 --瞬时表底
begin
--直接更新本装置的全部读取“瞬时表底”的数据状态为“已读取”
update [scyd].[dbo].[Comm_CommandInterface] set Status='补抄成功'
end

类似上面,将Update语句的Where条件去掉执行(通过调试知道Update语句是执行过的),但结果仍然不能成功更新。
chuifengde 2009-12-25
  • 打赏
  • 举报
回复
没看到什么问题,建议检查数据类型,长度等,可以先把复杂的逻辑注释掉用一个简单的逻辑测试一下
我用同样的方式(触发器中在游标中更新其它库)测试没问题
wooden954 2009-12-25
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 playwarcraft 的回复:]
把cursor定义为只读模式试试看

declare c1 INSENSITIVE cursor
for ....
[/Quote]
这个方法我试验了一下,不成!
wooden954 2009-12-25
  • 打赏
  • 举报
回复
自己再顶顶
wooden954 2009-12-24
  • 打赏
  • 举报
回复
To:五楼:
会执行到的
playwarcraft 2009-12-24
  • 打赏
  • 举报
回复
--更新数数据块首地址
if @LAddr_Start_DA<>''
UPDATE CommandHistoryDown SET LAddr_Start_DA = @LAddr_Start_DA WHERE ID = @DownRecID

这句会执行到么?。。。
playwarcraft 2009-12-24
  • 打赏
  • 举报
回复
把cursor定义为只读模式试试看

declare c1 INSENSITIVE cursor
for ....
xuejie09242 2009-12-24
  • 打赏
  • 举报
回复
是不是和操作的inserted逻辑表有关,先把数据放到另外一个表变量试一下。
wooden954 2009-12-24
  • 打赏
  • 举报
回复
补充:
我的问题其实很简单:就是既然在触发器中能够执行跨库的数据表更新,为什么使用了游标就不行了呢?是游标的原因,还是我的用法的原因?
dawugui 2009-12-24
  • 打赏
  • 举报
回复
最好给出完整的表结构,测试数据,计算方法和正确结果.


发帖注意事项
http://topic.csdn.net/u/20091130/21/fb718680-98ff-4afb-98d8-cff2f8293ed5.html?24281

22,209

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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