【问题标题】:My PL/SQL procedure exception doesn't seem to work我的 PL/SQL 过程异常似乎不起作用
【发布时间】: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

谢谢

【问题讨论】:

    标签: sql oracle plsql oracle-sqldeveloper plsqldeveloper


    【解决方案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 应该识别并实际反对指定如何完成某事的“要求”。规范应指定什么,而不是涉及具体实现的杂草。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-10
    相关资源
    最近更新 更多