我写了这个触发器来阻止数据库的写
create or replace trigger spese_autorizzate_trg
before insert or update on spese
for each row
declare
boolean integer := 0;
voceSpesa tipospesa.descrizione%TYPE := NULL;
begin
select
descrizione into voceSpesa
from
tipospesa
where
id = :new.tipospesa
and approvazione = 'n';
if voceSPesa is NULL then
raise_application_error(-20000, 'La spesa '||voceSpesa||' non è rimborsabile');
end if;
end;
如果tipospesa的值为4或5,则应阻止书写 但是当我插入这样的行
insert into spese(id, importo, tipospesa, data) values (4, 20, 3, TO_DATE('15-jul-18', 'DD-MON-RR'))
我有这个错误
Error report:
SQL Error: ORA-01403: no data found
ORA-06512: at "PARLAMENTO2018.SPESE_AUTORIZZATE_TRG", line 7
ORA-04088: error during execution of trigger
'PARLAMENTO2018.SPESE_AUTORIZZATE_TRG'
01403. 00000 - "no data found"
*Cause:
*Action:
并且写作没有完成。为什么?
答案 0 :(得分:0)
问题在于,如果表中没有返回任何行,则INTO
子句将失败,从而引发no_data_found
MAX
或MIN
给您NULL
。
select
MAX(descrizione) into voceSpesa
from
tipospesa
where
id = :new.tipospesa
and approvazione = 'n';
请记住,在列descrizione
本身为null
的情况下,该字段也将为null。但是,这完全取决于您的要求,如果发生这种情况,您将如何处理。
答案 1 :(得分:0)
在我看来,您似乎必须处理NO_DATA_FOUND
,而不是处理DESCRIZIONE
是NULL
的可能性。像这样:
create or replace trigger spese_autorizzate_trg
before insert or update on spese
for each row
declare
-- boolean integer := 0; -- Uh, no! Boolean is name of PL/SQL datatype;
-- don't use it as name of a variable
-- Besides, it is never used in your code.
voceSpesa tipospesa.descrizione%TYPE; -- No need to set it to NULL explicitly;
-- it is NULL anyway
begin
select descrizione
into voceSpesa
from tipospesa
where id = :new.tipospesa
and approvazione = 'n';
exception
when no_data_found then
raise_application_error(-20000, 'La spesa '||voceSpesa||' non è rimborsabile');
when too_many_rows then
-- what then? Do you know? Can that select return more than a single row? If so,
-- you should handle it
null;
end;
是的,您可以使用select max(descrizione) ...
保存一些键入内容,但这有点棘手。如果其他人继承了您的代码,他们是否会知道您使用MAX来避免NO_DATA_FOUND
,或者您是否有意选择该列的最大值?因此,我想说最好是处理您期望的异常,并避免任何疑问。