我正在使用Sql Developper,我在一个包中创建了以下过程:
PROCEDURE VALIDER(a_session IN NUMBER) AS
i NUMBER;
TYPE type_tab IS TABLE OF PANIER%ROWTYPE;
tabSeances type_tab;
BEGIN
SELECT * BULK COLLECT INTO tabSeances
FROM PANIER
WHERE a_session = sessionweb;
i:=0;
FOR i IN 1 .. tabSeances.count LOOP
-- UPADTE DU NOMBRE DE PLACES LIBRES
BEGIN
UPDATE PROJECTION
SET remaining_seats = (remaining_seats - tabseances(i).nbrplaces)
WHERE num_copy = tabseances(i).num_copy
AND day = tabseances(i).dateseance
AND time_slot = tabseances(i).time_slot
AND movie = tabseances(i).movie;
COMMIT;
--UPDATE ON PANIER
UPDATE PANIER
SET valide = 1
WHERE sessionweb = a_session
AND num_copy = tabseances(i).num_copy
AND dateseance = tabseances(i).dateseance
AND time_slot = tabseances(i).time_slot
AND movie = tabseances(i).movie;
COMMIT;
EXCEPTION
WHEN NO_DATA_FOUND THEN raise_application_error(-20035, 'Pas de données');
WHEN OTHERS THEN raise_application_error(-20006,'Autres Erreurs');
END;
END LOOP;
END VALIDER;
该过程正常执行,我没有收到错误。
我有一种产品车:“PANIER”。我在thsi cart中为一个人(会话)循环所有条目,以在数据库中验证它们并减少总座位数。
但是第一次更新中的“剩余座位”字段(来自PROJECTIONS)不起作用。该字段未更新。我已经尝试过其他值,但没有。
我确信该过程是executetd,因为第二次更新仍然有效。它将购物车条目标记为“已确认” 我在这个领域没有任何触发器。
我的表包含有效数据(<> NULL)。
我像这样执行这个程序(在BEGIN END;块中):
CMDPLACES.VALIDER(1);
感谢您的回复。
答案 0 :(得分:1)
首次更新时是day
还是dateseance
?
UPDATE PROJECTION
SET remaining_seats = (remaining_seats - tabseances(i).nbrplaces)
WHERE num_copy = tabseances(i).num_copy
AND dateseance = tabseances(i).dateseance
AND time_slot = tabseances(i).time_slot
AND movie = tabseances(i).movie;
同样提及 @TarttenKettner 时,日期中的时间戳数据在比较时可能会失败,因此我们使用{{TRUNCATE
时间戳数据TRUNC()
1}} [如果需要]!
如果日期列是索引,请注意数据库不会使用该索引。
要处理UPDATE
中的无数据,您可以检查(SQL%ROWCOUNT > 0)
以确定更新的行数!
答案 1 :(得分:0)
您的第一次更新会比较天数。这些数据类型是什么?如果您处理DATETIME,请确保在没有时间部分的情况下进行比较(如果有)。使用TRUNC实现此目的。
AND TRUNC(day) = TRUNC(tabseances(i).dateseance)