Domanda

Sto cercando di imporre l'integrità su una tabella in un modo che non credo che un Vincolo possa ...

CREATE TABLE myData
(
   id             INTEGER IDENTITY(1,1) NOT NULL,
   fk_item_id     INTEGER               NOT NULL,
   valid_from     DATETIME              NOT NULL,
   invlaid_from   DATETIME              NOT NULL
)

Il vincolo che voglio applicare è che non dovrebbero mai esserci voci per lo stesso " fk_item_id " con date sovrapposte.

Nota:

invalid_from è l'istante immediatamente successivo al periodo valido.
Ciò significa che i seguenti due periodi vanno bene ...

  • "01 gennaio 2008 00:00" - > "2008 01 feb 00:00" (tutto gennaio)
  • "2008 01 feb 00:00" - > "2008 mar 01 00:00" (tutto febbraio)

Posso controllare quella regola in un trigger. Quando il trigger trova un inserimento / aggiornamento illegale, tuttavia, qual è il modo migliore per impedire la "quotazione illegale" inserimenti / aggiornamenti da accadere?

(Se inserito include due record validi e due record non validi, posso interrompere solo i due record non validi?)

Saluti,
Dems.

Modifica

Nel caso precedente, un vincolo che utilizzava una funzione ha funzionato bene. Ma non ho mai capito perché RAISERROR non funzionasse nella versione trigger.

Ho pensato che fosse perché il trigger è un trigger DOPO, e che avrei bisogno di un trigger PRIMA, ma questa non sembra essere un'opzione ...

È stato utile?

Soluzione

Non puoi eliminare direttamente da inserito (gli aggiornamenti alle tabelle logiche generano un errore) ma puoi tornare alla tabella di origine come mostrato di seguito

create table triggertest (id int null, val varchar(20))
Go
create trigger after  on [dbo].triggertest
for Update  
as
Begin

    delete tt from triggertest tt inner join 
    inserted i on tt.id = i.id 
    where i.id = 9

End
GO
insert into triggertest values (1,'x')
insert into triggertest values (2,'y')
Update triggertest set id = 9 where id = 2
select * from triggertest
1, x

Inoltre, non è necessario seguire il percorso del trigger, è inoltre possibile associare un vincolo di controllo al valore restituito di una funzione

Alter table myData WITH NOCHECK add 
Constraint  CHK_VALID CHECK (dbo.fx_CheckValid(id, valid_from , invalid_from) = 1 );

Altri suggerimenti

Non cancellare i record dalla tabella inserita ... questo è un errore silenzioso. La strada per l'inferno è lastricata in Partial Commits.

Devi RAISERROR , che è essenzialmente ciò che un < a href = "http://msdn.microsoft.com/en-us/library/ms188066.aspx" rel = "nofollow noreferrer"> vincolo farebbe.

Il tuo trigger potrebbe modificare i valid_from e / o invlaid_from DATETIME dei " illegali " registra a valori speciali. Un successivo passaggio di pulizia potrebbe identificare "illegale" record.

Solleva un errore.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top