禁用触发器是否算作SQL Server中的架构更改?我收到错误:“无法完成游标操作,因为表架构已更改”
我有一个存储过程p_DeleteA,它从表A中删除一行,并从表B中删除所有子记录;但是,当表B中的一行被删除时,表C,D和E中的孙记录也会被删除。上面是通过光标在表B附近实现的,其中AId = xyz,然后调用p_DeleteB,删除C,D和E记录,然后是B.
在开发数据库中,该过程正常。但是,在构建环境中会出现上述错误。我可以想象的唯一可以算作“架构更改”的事实是,触发器被禁用以避免在表B上相互踩到。禁用触发器是否算作架构更改?如果不是,那么可能导致错误消息的假设是我没有在中间更改模式。我读到的自动收缩可能导致此错误,但是已关闭。
编辑:我正在模拟级联删除,但我手动删除了所有记录。
开发环境版本:9.00.4035.00
构建环境版本:9.00.1399.00
答案 0 :(得分:4)
认为我正在点击KB930775: FIX: Error message when you try to retrieve rows from a cursor that uses the OPTION (RECOMPILE) query hint in SQL Server 2005: "Could not complete cursor operation because the table schema changed after the cursor was declared或其他已知问题,我更新到SP3,但没有解决问题。
将光标声明为本地和静态似乎已经成功了:
DECLARE BCursor CURSOR LOCAL STATIC
FOR
SELECT BId
FROM B
WHERE AId = @AId
请参阅DECLARE CURSOR (Transact-SQL)。
STATIC
定义一个生成的游标 要使用的数据的临时副本 通过光标。所有要求 光标从这里回答tempdb
中的临时表;因此, 对基表进行的修改是 没有反映在返回的数据中 对此游标进行的提取,以及此操作 光标不允许修改。
答案 1 :(得分:3)
是。触发器create / drop / alter是表上的模式更改,将触发重新编译并使动态游标无效。
答案 2 :(得分:1)
添加或删除触发器是架构更改。由于这些确切类型的非确定性数据驱动副作用,触发器是一个痛苦的世界。总是避免触发因为它们使你的表dml非正交。
答案 3 :(得分:0)
所以...你的光标期待其他表中的记录,但是它发现它们不是。
但我很困惑 - 你是否开启了级联删除,或者你自己删除它们?你在谈论一个调用p_DeleteB的游标,这听起来不像是级联删除。
事实上,听起来你没有实施FK,这也不好。
如果我是你,我会在没有光标的情况下这样做 - 这可能很好地解决你的问题,因为没有光标,对模式的依赖不应该存在。