2009-05-27 11 views
1

テーブル制約は同じトランザクションで実行されますか?読み取りコミットされた分離レベルとテーブル制約とのトランザクション

テーブルにいくつかの行を挿入する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 

答えて

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) 
+0

私は行を削除したくありません。私はちょうど私が現在のトランザクションで挿入している行を見ることができるように(チェック制約によって呼び出される)関数が必要です。 – reticent

+0

@reticent - あなたが挿入している場合、関数は行を見るべきです。私が編集した例を参照してください。 – ahains

関連する問題