我必须将记录插入测试环境中的表中,以便我现在知道它将抛出主键约束违规。而且由于脚本在从环境迁移到另一个环境时将由其他人独立运行,我希望在遇到问题时让我的脚本回滚。
我的脚本如下:
use my_db
go
--
-- No rows of the given "my_code" must exist, as they shall be replaced.
--
if exists (
select 1
from my_table
where my_code like 'my_code'
) delete from my_table
where my_code like 'my_code'
--
-- All rows shall be inserted altogether, or rejected altogether at once.
--
begin tran a
insert into my_table (field1, field2, field3) values (value1, value2, value3)
if @@error != 0 or @@transtate != 0
begin
rollback tran a
end
insert into my_table (field1, field2, field3) values (value1, value2, value3)
if @@error != 0 or @@transtate != 0
begin
rollback tran a
end
commit tran a
go
我已经尝试过从这些帖子中得到的信息:
我试过只验证@@error
,@@transtate
和两者,并且我总是得到报告错误的消息框,并且没有回滚记录,也就是说,仍然插入了传递的行
我想知道是否有办法确保Sybase按预期充分处理事务,或者只是确保它在SQL Server允许时插入行时不自动提交行 - 我的意思是,SQL Server继承毕竟,从Sybase开始......它是Sybase的新手,还是SQL Server的新手,我不知道。
我希望避免出现错误,最好记录错误并回滚或删除事务中插入的行。
请注意,我不使用存储过程。此脚本是一次性更新数据库,以查找使用该数据库的软件中发生的最近更改。
答案 0 :(得分:2)
代码看起来大致正确。如果在插入时遇到重复键错误,那么这将被IF测试捕获。
但是,您还应该添加一些基于标志的逻辑(GOTO
或其他IF-ELSE
测试),当您决定回滚第一个插入时,它会跳过第二个插入。
目前,您的代码将始终执行第二次插入,无论如何。与其他一些数据库不同,在 ASE控制流不受错误条件影响,您需要自己拦截。
另请注意,两个插入都是相同的,因此如果表上有唯一索引,则第二个插入将始终生成重复键错误,如果第一个插入成功。
听起来好像您正在使用客户端在每个语句之后检查状态? ASE本身不会弹出任何错误消息框。
要开发它,最好使用
从命令行运行脚本isql [...] -i yourscriptfile.sql
只有两个评论:
如果在执行此代码时已经激活了事务,则实际上会发生上一个项目符号中的此问题。您应该始终使用
在脚本的开头进行检查if @@ trancount> 0 开始 print'错误:事务已处于活动状态' 返回 结束
或类似的东西。
HTH,
Rob V。