【发布时间】: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(逐行处理)处理 - 尤其是不在触发器中!!
标签: sql sql-server tsql database-cursor