sql - 收到错误“回滚事务请求没有相应的开始事务”
问题描述
我正在尝试创建一个触发器,由于某种原因,第二个 if 语句破坏了我的代码。
如果我删除第二个 if 语句,代码将起作用。我得到的错误是:
回滚事务请求没有对应的开始事务
我的代码:
create trigger insertemployee
on jobinsailing
after insert
as
BEGIN TRANSACTION
declare @sailingID int,
@employeeID char(9),
@jobTitle varchar(10),
@sailingStartDate date,
@sailingEndDate date
select @sailingId = inserted.sailingid,
@employeeID = inserted.employeeid,
@jobTitle = inserted.jobtitle,
@sailingStartDate = sailing.leavingtime,
@sailingEndDate = sailing.returntime
from inserted
inner join sailing
on inserted.sailingid = sailing.sailingid
if exists(select employeeid
from sailing
inner join jobinsailing
on sailing.sailingid = jobinsailing.sailingid
where ( @sailingStartDate <= returntime )
and ( leavingtime <= @sailingEndDate )
and employeeid = @employeeID) rollback TRANSACTION;
else if exists((select sailing.sailingid
from sailing
inner join jobinsailing
on jobinsailing.sailingid = sailing.sailingid
where Datediff(day, @sailingStartDate, sailing.leavingtime) <= 4
or Datediff(day, @sailingEndDate,sailing.leavingtime) <= 4
or Datediff(day, @sailingStartDate,sailing.returntime) <= 4
or Datediff(day, @sailingEndDate,sailing.returntime) <= 4
)) rollback TRANSACTION;
COMMIT TRANSACTION
解决方案
条件插入
您要实现的是使用触发器有条件地将记录插入表中。
这通常是一种不好的方法。您的代码(存储过程和/或业务层代码)应确定是否应在插入记录之前先插入记录。触发器并不是最好的工具——它们旨在让您强制执行复杂的约束。
假设你必须使用触发器,那么我建议你使用INSTEAD OF
触发器。它们旨在覆盖通常发生的默认插入过程,并允许您插入(或不插入)数据,而不必回滚事务。
多行插入
正如@DaleBurrell 指出的那样,每次插入操作都会执行一次触发器,并且inserted
表可以包含多行。最好对触发器进行编码,使其允许多行操作,但您也可以通过将此行添加到触发器的顶部来强制执行单行操作IF (ROWCOUNT_BIG() > 1) ROLLBACK
。
进一步阅读
推荐阅读
- tomcat9 - 错误的应用程序名称:tomcat9.exe
- c++ - 从另一个链表创建链表时出错?
- node.js - 出现错误:在 Nightwatchjs 中设置调试器时
- c# - 访问图表的 X 轴并动态设置标签之间的间隔
- reactjs - useEffect() 函数只运行一次,store 稍后更新(React hooks)
- pine-script - 在某些交易对上传递小于 1 的浮点数时出现错误“传递的值为 0.000000”
- node.js - 如何在服务器上自动运行 node.js 代码?
- python - 无休止的 AWS lambda 请求从/向 s3 读取和写入到同一个存储桶
- flutter - 来自 json API 响应的列表
- azure-active-directory - Azure AD 的公共证书