表约束是否在同一个事务中执行?
我有一个具有Read Committed隔离级别的事务,它在表中插入一些行。该表有一个约束,它调用一个函数,该函数又从同一个表中选择一些行。
看起来函数在不知道任何事务的情况下运行,函数中的select返回事务中表中的行。
有解决方法还是我遗漏了什么?感谢。
以下是交易和约束的代码:
insert into Treasury.DariaftPardakhtDarkhastFaktor
(DarkhastFaktor, DariaftPardakht, Mablagh, CodeVazeiat,
ZamaneTakhsiseFaktor, MarkazPakhsh, ShomarehFaktor, User)
values
(@DarkhastFaktor, @DariaftPardakht, @Mablagh, @CodeVazeiat,
@ZamaneTakhsiseFaktor, @MarkazPakhsh, @ShomarehFaktor, @User);
constraint expression (enforce for inserts and updates):
([Treasury].[ufnCheckDarkhastFaktorMablaghConstraint]([DarkhastFaktor])=(1))
ufnCheckDarkhastFaktorMablaghConstraint:
returns bit
as
begin
declare @SumMablagh float
declare @Mablagh float
select @SumMablagh = isnull(sum(Mablagh), 0)
from Treasury.DariaftPardakhtDarkhastFaktor
where DarkhastFaktor= @DarkhastFaktor
select @Mablagh = isnull(MablaghKhalesFaktor, 0)
from Sales.DarkhastFaktor
where DarkhastFaktor= @DarkhastFaktor
if @Mablagh - @SumMablagh < -1
return 0
return 1
end
答案 0 :(得分:3)
检查约束不会对删除操作强制执行,请参阅http://msdn.microsoft.com/en-us/library/ms188258.aspx
未验证CHECK约束 在DELETE语句中。因此, 在表上执行DELETE语句 有某些类型的支票 约束可能产生意外 结果
编辑 - 要回答有关变通方法的问题,如果函数调用显示不变量已损坏,则可以使用删除触发器回滚。
编辑#2 - @reticent,如果要添加行,则检查约束调用的函数实际上应该看到行。如果没有,检查约束将是无用的。这是一个简单的例子,你会发现前两个插入成功,第三个插入失败:
create table t1 (id int)
go
create function t1_validateSingleton ()
returns bit
as
begin
declare @ret bit
set @ret = 1
if exists (
select count(*)
from t1
group by id
having count(*) > 1
)
begin
set @ret = 0
end
return (@ret)
end
go
alter table t1
add constraint t1_singleton
check (dbo.t1_validateSingleton()=1)
go
insert t1 values (1)
insert t1 values (2)
insert t1 values (1)