1

テーブル制約は同じトランザクションで実行されますか?

テーブルにいくつかの行を挿入する読み取りコミット分離レベルのトランザクションがあります。テーブルには、同じテーブルからいくつかの行を選択する関数を呼び出す制約があります。

関数はトランザクションについて何も知らずに実行されているように見え、関数の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
4

1 に答える 1

3

チェック制約は削除操作に適用されません。http://msdn.microsoft.com/en-us/library/ms188258.aspxを参照してください。

CHECK制約は、DELETEステートメント中に検証されません。したがって、特定のタイプのチェック制約がある表に対してDELETEステートメントを実行すると、予期しない結果が生じる可能性があります。

編集-回避策に関する質問に答えるために、関数呼び出しが不変条件が壊れていることを示した場合、削除トリガーを使用してロールバックできます。

編集#2-@reticent、行を追加する場合、チェック制約によって呼び出される関数は実際に行を参照する必要があります。そうでなければ、チェック制約は役に立たないでしょう。簡単な例を次に示します。最初の2つの挿入は成功し、3番目の挿入は期待どおりに失敗します。

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)
于 2009-05-27T13:26:16.883 に答える