2015-02-28 15 views
18

Ich habe diesen Trigger:Warum bekomme ich "Ein Cursor mit dem Namen existiert schon"?

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 

Wenn ich auf die Tabelle ein Insert tun TDINCI

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

Ich erhalte eine Fehlermeldung:

A cursor with the name 'detailsCursor' already exists.

Ich öffne

open detailsCursor; 

und schließen Sie den Cursor.

close detailsCursor; 
deallocate detailsCursor; 

Vielleicht gibt es etwas mit dem Umfang des Cursors, die ich nicht verwalte? Danke im Voraus.

+3

Ihre Trigger hat ** MAJOR ** Fehler, dass Sie scheinen anzunehmen, es ** einmal pro Zeile genannt werde ** - das ist ** nicht ** die Fall. Der Trigger wird ** einmal pro Anweisung ** ausgelöst. Wenn also Ihre INSERT-Anweisungen 25 Zeilen betreffen, erhalten Sie den Trigger ** einmal ausgelöst **, aber dann enthält "Insert" jeweils 25 Zeilen. Welche dieser 25 Zeilen wird Ihr Code hier auswählen? wähle @incidentCode = CO_INCI von insert; '- es ist nicht deterministisch - einer wird ausgewählt alle anderen ** ignoriert **. Sie müssen Ihren Trigger neu schreiben, um dies zu berücksichtigen! Außerdem: *** bitte vermeiden Cursor *** - vor allem in einem Trigger !!!!!!!! –

+1

Wenn Sie sich immer noch dafür entscheiden, Cursor zu verwenden, sollten Sie die Optionen für den Deklarationscursor überprüfen, zumindest local, read only, forward_only/fast_forward –

+0

@marc_s Wenn ich Cursor nicht verwenden kann, würde ich alle Daten in der eingefügten Tabelle abrufen: I machte etwas wie: 'DECLARE ALLDATAINSERTED CURSOR LOKAL FÜR \t Wählen Sie * von eingefügt;' –

Antwort

37

Sie verwenden den globalen Cursor, der bei jedem Aufruf dieser Prozedur definiert wird und Ihnen den gleichen Fehler gibt.

Definieren Sie einen lokalen Cursor. Setzen Sie einfach das Stichwort LOCAL nach CURSOR:

declare detailsCursor CURSOR LOCAL FOR 
... 
Verwandte Themen