2015-02-28 6 views
18

Ho questo grilletto:Perché compare "Un cursore con il nome esiste già"?

CREATE TRIGGER CHECKINGMAXQTYDAYSVACANCY 
    ON TDINCI 
AFTER INSERT 
AS 
    DECLARE 
     @incidentCode int, 
     @dateStart datetime, 
     @dateEnd datetime, 
     @daysAccumulated int, 
     @maxDaysAvailable int 

    set @daysAccumulated = 0; 

    select @incidentCode = CO_INCI from inserted; 
    select @maxDaysAvailable = IN_DIAS_GANA from TCINCI 
     where CO_INCI = @incidentCode; 

    declare detailsCursor CURSOR FOR 
     select FE_INIC, FE_FINA from TDINCI 
     where CO_INCI = @incidentCode; 

    open detailsCursor; 

    if CURSOR_STATUS('variable', 'detailsCursor') >= 0 
    begin 
     fetch next from detailsCursor 
      into @dateStart, @dateEnd; 

     while @@FETCH_STATUS = 0 
     begin 
      set @daysAccumulated = @daysAccumulated + (DATEDIFF(DAY, @dateStart, @dateEnd) + 1); 

      fetch next from detailsCursor 
      into @dateStart, @dateEnd; 
     end 
     close detailsCursor; 
     deallocate detailsCursor; 
    end 
    IF(@maxDaysAvailable > @daysAccumulated) 
    BEGIN 
     RAISERROR ('No se pueden ingresar mas dias de los programados en la cabecera de incidencias.', 16, 1); 
     ROLLBACK TRANSACTION; 
     RETURN 
    END 
GO 

Quando faccio un'Inserisci per la tavola TDINCI

INSERT INTO TDINCI 
VALUES (1, '20150101', '20150115', '2015-2015') 

ottengo un errore:

A cursor with the name 'detailsCursor' already exists.

apro

open detailsCursor; 

e chiudere il cursore.

close detailsCursor; 
deallocate detailsCursor; 

Forse c'è qualcosa con l'ambito del cursore che non riesco a gestire? Grazie in anticipo.

+3

il trigger ha ** ** MAJOR difetto che sembra presumere che sarà chiamato ** ** una volta per riga - che è ** non ** il Astuccio. Il trigger scatterà ** una volta per istruzione **, quindi se le tue istruzioni "INSERT" riguardano 25 righe, il trigger verrà attivato ** una volta **, ma "Inserito" conterrà ciascuna 25 righe. Quale di quelle 25 righe sceglierà il tuo codice qui ?? seleziona @incidentCode = CO_INCI da inserito; '- non è deterministico - verrà selezionato tutti gli altri ** ignorati **. È necessario riscrivere il trigger per tenerne conto! Inoltre: *** per favore evita i cursori *** - specialmente all'interno di un grilletto !!!!!!!! –

+1

Se si decide ancora di utilizzare i cursori, è necessario verificare le opzioni del cursore di dichiarazione, almeno locale, sola lettura, forward_only/fast_forward –

+0

@marc_s Se non riesco a utilizzare i cursori come recuperare tutti i dati nella tabella inserita: I stava facendo qualcosa del tipo: 'DICHIARARE CURSORE ALLDATAINSERITO LOCALE PER \t seleziona * da inserito;' –

risposta

37

Si sta utilizzando il cursore globale che verrà definito ogni volta che si chiama questa procedura e si dà lo stesso errore.

Definire un cursore locale. Basta mettere la parola LOCAL dopo CURSOR:

declare detailsCursor CURSOR LOCAL FOR 
...