我很难理解我的pl / sql触发器有什么问题。 错误是: 错误报告 - SQL错误:ORA-01422:精确提取返回超过请求的行数 ORA-06512:at" SYSTEM.TRG_LATE_RETURN",第6行 ORA-04088:执行触发器时出错&SYSTEM; TRG_LATE_RETURN' 01422. 00000 - "确切的提取返回超过请求的行数" *原因:精确提取中指定的数字小于返回的行数。 *操作:重写查询或更改请求的行数
我的触发器如下:
create or replace trigger trg_late_return
before update of DETAIL_RETURNDATE, DETAIL_DUEDATE on TY_DETAILRENTAL
declare
temp_date DATE:= SYSDATE;
temp_due_date DATE:= SYSDATE;
BEGIN
select DETAIL_RETURNDATE
into temp_date
from TY_DETAILRENTAL;
select DETAIL_DUEDATE
into temp_due_date
from TY_DETAILRENTAL;
IF temp_date is null
THEN
update TY_DETAILRENTAL
set DETAIL_DAYSLATE=null;
END IF;
if temp_date <> null
THEN
if temp_date = trunc(temp_due_date) + 1
then
update TY_DETAILRENTAL
set DETAIL_DAYSLATE=0;
end if;
if temp_date > trunc(temp_due_date) + 1
then
update TY_DETAILRENTAL
set DETAIL_DAYSLATE = DETAIL_RETURNDATE - DETAIL_DUEDATE;
end if;
end if;
END;
/
SQL和PL / SQL的新手,所以我将不胜感激。
答案 0 :(得分:0)
您的查询或更新都没有过滤器(where子句),因此您正在处理整个表格 - 这可能不是您的意图。您试图将这些列的所有值都添加到标量变量中,这些变量只能包含一个值。
触发器也针对您查询和更新的同一个表,这表明您实际上意味着这是(或者需要这样)行级触发器,而不是语句级触发器。
这意味着您需要将for each row
添加到定义中,而不是重新查询和更新表,您可以对可用于行级触发器的new
伪记录进行操作。
您也无法使用<>
与null进行比较;您已使用is null
,而其相反的是is not null
。虽然你也可以在这里使用else
。
所以这可能是你想要的:
create or replace trigger trg_late_return
before update of detail_returndate, detail_duedate
on ty_detailrental
for each row
begin
if :new.detail_returndate is null
then
:new.detail_dayslate := null;
else
if :new.detail_returndate = trunc(:new.detail_duedate) + 1
then
:new.detail_dayslate := 0;
elsif :new.detail_returndate > trunc(:new.detail_duedate) + 1
then
:new.detail_dayslate := :new.detail_returndate - :new.detail_duedate;
end if;
end if;
end;
/
在比较它们时,您可以使用:new
引用更新的列值,因此您不需要这些值的局部变量副本。 (您也可以使用:old
查看更新前的值,但这里似乎并不需要。)
当最终更新数据库中的实际匹配行时,将使用对new
伪记录所做的更改。
Read more about the new/old pseudorecords,以及triggers in general。