Domanda

La vincoli di tabella vengono eseguiti nella stessa transazione?

Ho una transazione con livello di isolamento Read Committed che inserisce alcune righe in una tabella. La tabella include un vincolo su di esso che chiama una funzione che a sua volta seleziona alcune righe dalla stessa tabella.

Sembra che la funzione viene eseguito senza sapere nulla della transazione e di selezione nella funzione restituisce righe della tabella che erano lì prima della transazione.

C'è una soluzione o mi sto perdendo qualcosa? Grazie.

Ecco i codici per la transazione e il vincolo:

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
È stato utile?

Soluzione

Vedi i vincoli non vengono applicate per le operazioni di eliminazione, vedi http: // msdn .microsoft.com / en-us / library / ms188258.aspx

  

VEDI vincoli non vengono convalidati   durante istruzioni DELETE. Perciò,   l'esecuzione di istruzioni DELETE sui tavoli   con alcuni tipi di controllo   vincoli possono produrre inaspettati   risultati.

Modifica - per rispondere alla tua domanda sulla soluzione, è possibile utilizzare un trigger di eliminazione per ripristinare se la chiamata di funzione mostra un invariante è rotto

.

Modifica # 2 - @reticent, se si sta aggiungendo le righe allora la funzione chiamata dal vincolo di controllo dovrebbe infatti vedere le righe. Se non lo fa, vincoli di controllo sarebbe inutile. Ecco un semplice esempio, vi accorgerete che i primi 2 inserti successo e il terzo non riesce come previsto:

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)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top