TL; DR:我的真正问题在于标题,是否可以在事务完成之前阻止表插入,也就是说,只关注数据,因为它可能是在提交交易之前?
更新 :什么程序仅仅是一个人为的例子,可能不是一个好的例子,证明我无法想出阻止插入/更新的方法在完成包含两个语句的事务之前。我只是想知道是否有办法做到这一点,这个例子有点无关紧要。
(可能不好)示例:
如果两个表的某些属性被破坏,我试图阻止事务发生,一个简单的例子假设我想阻止第一个表的值之一(比如ID)已经存在于表2中。
OperationStatusResponse
我想失败的是:
create table dbo.tbl1
(
id int,
name varchar(20)
)
create table dbo.tbl2
(
id int,
name varchar(20)
)
go
因为在事务结束时,第一个表的id值与表2中的值相同。
但不幸的是,我已经尝试定义阻止此操作的触发器和检查约束,并且似乎都没有阻止它。
触发器(as suggested here):
begin transaction
insert into tbl1 values(1, 'tbl1_1')
insert into tbl2 values(1, 'tbl2_1')
commit transaction
检查约束(as suggested here):
CREATE TRIGGER MyTrigger ON dbo.tbl1
AFTER INSERT, UPDATE
AS
if exists ( select * from tbl2 inner join inserted i on i.id = tbl2.id)
begin
rollback
RAISERROR ('Duplicate Data', 16, 1);
end
如何更新我的代码以成功阻止交易?我是否需要将交易重新定义为同一时间?
答案 0 :(得分:0)
尝试更改触发器以在事件之前触发,如:
CREATE TRIGGER MyTrigger ON dbo.tbl1
BEFORE INSERT, UPDATE -- this is changed to "BEFORE"
AS
if exists ( select * from tbl2 inner join inserted i on i.id = tbl2.id)
begin
rollback
RAISERROR ('Duplicate Data', 16, 1);
end
注意:
检查约束只能检查表本身。
您还应该学习FOREIGN KEYS,因为这正是解决您遇到的问题的原因。
答案 1 :(得分:0)
不,你不可能在MSSQLSever中做你想做的事情,但它可能在PostGres或Oracle中。
原因第1部分:It's not possible to insert to two different tables in the same statement.
因此,SQLServer中不可能对多个表的表插入有一个约束,该表将在任意事务完成之前阻塞。
值得一提的是,你想要的是一个可延迟的约束。 See more about that here.