in

UGISS Community

Il sito della community dello User Group Italiano di SQL Server

Problema creazione trigger

Last post 01-25-2010 17.54 by dmauri. 1 replies.
Page 1 of 1 (2 items)
Sort Posts: Previous Next
  • 01-25-2010 13.48

    Problema creazione trigger

     Salve a tutti, vi scrivo per chiedere aiuto per la creazione di un trigger in SQL Server. La tabella in questione è la seguente:

    CREATE TABLE edizione (
    id_edizione int PRIMARY KEY,
    data_inizio date,
    data_fine date,
    corso nchar[5] REFERENCES corso(codice_corso)
    )

    Vorrei creare un trigger che al momento dell'insert permetta di inserire una edizione di un corso solo se la sua data di inizio è maggiore della data di fine delle altre edizioni (dello stesso corso) eventualmente già inserite.

    Ho provato a scriverlo (allego il codice a fine post) ma per qualche ragione che non riesco a comprendere esso impedisce l'inserimento di qualsiasi nuova edizione, anche se non rientra nei parametri specificati sopra.
     
    Prima prova
    CREATE TRIGGER TR_date
    ON  dbo.edizione
    AFTER INSERT, UPDATE
    AS
    DECLARE @data_inizio date, @data_fine date
    SELECT @data_inizio = inserted.data_inizio, @data_fine = edizione.data_fine
    FROM edizione INNER JOIN inserted
    WHERE edizione.corso = inserted.corso

    IF @data_fine >= @data_inizio
    BEGIN
        -- SET NOCOUNT ON added to prevent extra result sets from
        -- interfering with SELECT statements.
        SET NOCOUNT ON;

        -- Insert statements for trigger here
       ROLLBACK TRAN
       PRINT 'Errore: una edizione deve iniziare dopo la conclusione dell altra'
    END
    GO

    Seconda Prova

    CREATE TRIGGER [dbo].[TR_date]
    ON  [dbo].[edizione]
    AFTER INSERT, UPDATE
    AS
    DECLARE @data_inizio date, @data_fine date, @corso nchar(5)
    SET @data_inizio = (SELECT inserted.[data_inizio] FROM inserted)
     SET @corso = (SELECT inserted.[corso] FROM inserted)
    SET @data_fine = (SELECT edizione.[data_fine] FROM edizione WHERE corso = @corso)

    IF @data_fine >= @data_inizio
    BEGIN
        -- SET NOCOUNT ON added to prevent extra result sets from
         -- interfering with SELECT statements.
        SET NOCOUNT ON;

        -- Insert statements for trigger here
       ROLLBACK TRAN
       PRINT 'Errore: una edizione deve iniziare dopo la conclusione dell altra'
     END

    Grazie in anticipo per l'aiuto!

    Filed under: ,
    • Post Points: 20
  • 01-25-2010 17.54 In reply to

    • dmauri
    • Top 10 Contributor
      Male
    • Joined on 05-14-2007
    • Novate Milanese
    • Posts 1.907
    • Points 24.955

    Re: Problema creazione trigger

    La cosa è un pò più complessa di quello che sembra. Per iniziare prova a scaricare Slide e Demo riguardo alle problematiche temporali che trovi qui:

    http://community.ugiss.org/files/folders/workshop_20071003/default.aspx

    Nel tuo trigger vai ad assegnare ad una variable il valore proveniente dalla tabella edizioni, ma in nessun modo ti garantisci il fatto che da quella tabella venga preso il valore ultimo inserito prima di quello attuale, quindi in pratica SQL Server te ne rida uno a caso. Una soluzione di esempio è questa:

    alter trigger dbo.tg__edizione_iu
    on dbo.edizione
    after insert, update
    as
    set nocount on
    if exists(
     select
      *
     from
      inserted i inner join dbo.edizione e on
        i.corso = e.corso and
        e.id_edizione <> i.id_edizione and  
        i.data_inizio < e.data_fine
    ) begin
     rollback transaction
    end
    go

    In pratica si inverte la logica e si verifica che non ci sia alcun corso a cui data di fine è minore della date di inizio del corso che si sta inserendo.

    E' anche importante andare in JOIN con la tabella edizione evitando di prendere la riga che ha scatenato l'esecuzione del trigger, altrimenti un questa logica conterebbe anche se stessa andando quindi a dare sempre un risposta positiva (ossia che è vero che ci sono delle edizioni già in corso in quella data) e quindi annullerebbe la transazione.

    Io ho fatto solo un piccolo esempio, verifica che funzioni tutto anche nel caso di UPDATE e di operazioni su più righe (ad es: cosa succede se fai INSERT INTO ... SELECT per rimpire la tabella edizioni? il trigger è in grado di gestire correttamente più di una riga?)

    Per queste cose slide e demo consigliate in precedenza di saranno di GRANDE aiuto :-)

    Davide Mauri
    Microsoft MVP - SQL Server, MCP, MCAD, MCDBA, MCT - http://www.davidemauri.it
    Socio Fondatore e Mentor di Solid Quality Learning Italy - http://www.solidq.com
    Presidente di UGISS: User Group Italiano Sql Server - http://www.ugiss.org
    • Post Points: 5
Page 1 of 1 (2 items)
(C) 2007 User Group Italiano di SQL Server