为啥我会得到“名称已存在的游标”?

Posted

技术标签:

【中文标题】为啥我会得到“名称已存在的游标”?【英文标题】:Why do I get "A cursor with the name already exists"?为什么我会得到“名称已存在的游标”? 【发布时间】:2015-05-01 09:44:57 【问题描述】:

我有这个触发器:

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

当我对表 TDINCI 进行插入时

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

我得到一个错误:

名称为“detailsCursor”的游标已存在。

我打开

open detailsCursor;

并关闭光标。

close detailsCursor;
deallocate detailsCursor;

也许我无法管理光标范围内的某些东西?提前致谢。

【问题讨论】:

您的触发器有 MAJOR 缺陷,因为您似乎认为它会每行调用一次 - 那是不是 b> 情况。触发器将每条语句触发一次,因此如果您的 INSERT 语句影响 25 行,您将触发触发器一次,但随后 Inserted 将包含25 行。您的代码将在这 25 行中选择哪一行?从插入中选择@incidentCode = CO_INCI;` - 它是不确定的 - 将选择所有其他忽略。您需要重写触发器以考虑到这一点!另外:请避免使用光标 - 尤其是在触发器内!!!!!!!!! 如果你仍然决定使用游标,你真的应该检查声明游标选项,至少本地、只读、forward_only / fast_forward @marc_s 如果我不能使用游标如何获取插入表中的所有数据:我正在做类似的事情:DECLARE ALLDATAINSERTED CURSOR LOCAL FOR select * from inserted; @ErickAstoOblitas:使用 基于集合的 方法 - 使用 INSERT INTO .... SELECT .... 或类似的方法 - 不要进行 RBAR(逐行处理)处理 - 尤其是不在触发器中!! 【参考方案1】:

您正在使用每次调用此过程时都会定义的全局游标,并给您同样的错误。

定义一个本地游标。只需将关键字LOCAL 放在CURSOR 之后即可:

declare detailsCursor CURSOR LOCAL FOR
...

【讨论】:

有什么区别?

以上是关于为啥我会得到“名称已存在的游标”?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 javafx 会破坏我的半透明游标?

为啥我会得到这个错误的输出?

为啥我会得到不同形状的张量错误?

施放 pParam 后,为啥我会得到随机字符?

为啥我会得到 SP2-0253

为啥我会得到“未处理的异常类型 IOException”?