我的 PL/SQL 过程异常似乎不起作用
Posted
技术标签:
【中文标题】我的 PL/SQL 过程异常似乎不起作用【英文标题】:My PL/SQL procedure exception doesn't seem to work 【发布时间】:2020-11-09 13:10:05 【问题描述】:我有一个包含大陆的数据库,我想创建一个向数据库添加新大陆的过程,但有例外。我尝试通过创建一个已经存在的大陆(亚洲)来执行我的包 GEST_GEO 中的过程,并且没有引发我的异常。有谁知道为什么它不起作用? (nom 是名字)
这是我的代码:
CREATE OR REPLACE PACKAGE GEST_GEO AS
Procedure ADDCONTINENT(pnom continent.nom%TYPE, psuperficie continent.superficie%TYPE);
END GEST_GEO;
/
CREATE OR REPLACE PACKAGE BODY GEST_GEO AS
-- ADDCONTINENT
Procedure ADDCONTINENT(pnom CONTINENT.NOM%TYPE, psuperficie CONTINENT.SUPERFICIE%TYPE) IS
BEGIN
INSERT INTO CONTINENT VALUES (pnom, psuperficie);
COMMIT;
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN DBMS_OUTPUT.PUT_LINE('The continent already exists');
WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE(SQLCODE || '–' || SQLERRM);
END ADDCONTINENT;
END GEST_GEO;
/
execute GEST_GEO.ADDCONTINENT('Asia',99380);
执行时它只会告诉我PL/SQL procedure successfully completed
谢谢
【问题讨论】:
【参考方案1】:DUP_VAL_ON_INDEX
假定有一个主键或唯一键,或对该列强制执行的唯一索引。如果没有,Oracle 不知道有任何“重复”的内容,因此它会插入一行。
因此,创建前面提到的东西(键/索引)。
这是一个例子:table first(注意第 2 行的主键约束):
SQL> create table continent
2 (nom varchar2(30) constraint pk_cont primary key,
3 superficie number
4 );
Table created.
程序:注意
第 5 行 - 在INSERT
语句中始终包含目标列名称
异常处理部分:不要输出消息 - 除非您使用的工具支持它,否则任何人都看不到缓冲区的内容。 RAISE
改为错误
不要在过程中提交;让调用者决定是否提交
所以:
SQL> create or replace procedure addcontinent
2 (pnom continent.nom%type, psuperficie continent.superficie%type)
3 is
4 begin
5 insert into continent (nom, superficie) values (pnom, psuperficie);
6 exception
7 when dup_val_on_index then
8 raise_application_error(-20001, 'The continent already exists');
9 when others then
10 raise;
11 end addcontinent;
12 /
Procedure created.
测试:
SQL> exec addcontinent('Asia', 99380);
PL/SQL procedure successfully completed.
SQL> exec addcontinent('Asia', 99380);
BEGIN addcontinent('Asia', 99380); END;
*
ERROR at line 1:
ORA-20001: The continent already exists
ORA-06512: at "SCOTT.ADDCONTINENT", line 8
ORA-06512: at line 1
SQL> select * from continent;
NOM SUPERFICIE
------------------------------ ----------
Asia 99380
SQL>
【讨论】:
我明白了!创建密钥是什么意思?还有其他方法,例如编写我自己的异常吗? "创建键是什么意思" - 在您的 CONTINENT 表上创建一个主键。但是,天哪,只有 5 个大洲(如果算上澳大利亚和格陵兰,则有 6 或 7 个)。你真的需要一个程序来做到这一点吗?该程序将被调用多少次,以证明这种努力是合理的?此外, dbms_output.put_line 只是写入缓冲区。由客户端程序来处理和显示该缓冲区。在 sqlplus 中,在调用过程之前设置 SERVEROUTPUT ON。 这是一个练习,这是我的教授问的,所以我真的不知道我是否可以添加主键。这就是为什么我想知道是否有其他解决方案 另一个行动诅咒。加个PK就行了,别问了。也许你的导师想看看你是否把所有东西放在一起来解决问题。当您在现场时,您不会被灌输信息,尤其是设计问题,这将是您的责任。但@EdStevens 是对的,在你完全理解之前不要停止提问。 @Belayer - 您提出了一个很好的观点,即在没有具体细节的情况下,教师(希望!)希望了解学生如何解决问题。相反,在实际工作情况下,开发人员/dba 应该识别并实际反对指定如何完成某事的“要求”。规范应指定什么,而不是涉及具体实现的杂草。以上是关于我的 PL/SQL 过程异常似乎不起作用的主要内容,如果未能解决你的问题,请参考以下文章
PL/SQL NVL 和 OracleParameter 在 C# 中不起作用