gpt4 book ai didi

Oracle raise_application_error 错误号最佳实践

转载 作者:行者123 更新时间:2023-12-04 23:17:37 25 4
gpt4 key购买 nike

我有一个关于引发应用程序错误的错误代码(-20000 到 -20999)的问题。

  • 我们可以在 PLSQL 代码中的多个位置仅对不同的错误场景使用相同的错误代码(例如 -20000)吗?
  • 如果我们可以在所有地方使用相同的错误代码,为什么我们有 1000 个代码?
  • 在引发应用程序错误中使用错误代码的最佳做法是什么?

  • 示例代码:
    create table t(id number primary key);

    declare
    begin
    insert into t(id) values (1);
    insert into t(id) values (1);
    commit;
    exception
    when dup_val_on_index
    then
    raise_application_error(-20000, 'Cannot Insert duplicates');
    when others
    then
    raise_application_error(-20000, sqlcode||'-'||sqlerrm);
    end;

    最佳答案

  • 我们可以在 PLSQL 代码中的多个位置仅对不同的错误场景使用相同的错误代码(例如 -20000)吗?

  • 正如贾斯汀指出的那样,您当然可以这样做 - 只需使用一个代码。但这很可能会导致混淆。我已经看到它完成了,并且通常在这种情况下,开发人员只是将所有关键信息嵌入到消息中,甚至包括代码(例如,他们可能已经使用了超出可接受范围的自己的错误代码)。

    我建议您遵循 Oracle 的做法:为应用程序的区域分配范围,然后在该部分的该部分发生特定于应用程序的错误时使用范围内的错误代码。
  • 如果我们可以在所有地方使用相同的错误代码,为什么我们有 1000 个代码?

  • 看上面。
  • 在引发应用程序错误中使用错误代码的最佳做法是什么?

  • 创建一个表,您可以在其中“注册”所使用的错误代码以及消息。然后开发人员可以检查“他们的”错误是否已经注册并可以重新使用它。或者,更有可能的是,他们注册了一个新的错误代码和消息。

    无论哪种方式,您都有一个中心点来组织代码,并希望最大限度地减少使用相同错误代码的两个开发人员的更改。

    这是一个执行我上面建议的脚本,以及一个实用程序来生成一个包,其中包含所有定义的错误并可用于“软编码”引用。
    CREATE TABLE msg_info (
    msgcode INTEGER,
    msgtype VARCHAR2(30),
    msgtext VARCHAR2(2000),
    msgname VARCHAR2(30),
    description VARCHAR2(2000)
    );

    CREATE OR REPLACE PACKAGE msginfo
    IS
    FUNCTION text (
    code_in IN INTEGER
    , type_in IN VARCHAR2
    , use_sqlerrm IN BOOLEAN := TRUE
    )
    RETURN VARCHAR2;

    FUNCTION name (code_in IN INTEGER, type_in IN VARCHAR2)
    RETURN VARCHAR2;

    PROCEDURE genpkg (
    NAME_IN IN VARCHAR2
    , oradev_use IN BOOLEAN := FALSE
    , to_file_in IN BOOLEAN := TRUE
    , dir_in IN VARCHAR2 := 'DEMO' -- UTL_FILE directory
    , ext_in IN VARCHAR2 := 'pkg'
    );
    END;
    /

    CREATE OR REPLACE PACKAGE BODY msginfo
    IS
    FUNCTION msgrow (code_in IN INTEGER, type_in IN VARCHAR2)
    RETURN msg_info%ROWTYPE
    IS
    CURSOR msg_cur
    IS
    SELECT *
    FROM msg_info
    WHERE msgtype = type_in AND msgcode = code_in;

    msg_rec msg_info%ROWTYPE;
    BEGIN
    OPEN msg_cur;
    FETCH msg_cur INTO msg_rec;
    CLOSE msg_cur;
    RETURN msg_rec;
    END;

    FUNCTION text (
    code_in IN INTEGER
    , type_in IN VARCHAR2
    , use_sqlerrm IN BOOLEAN := TRUE
    )
    RETURN VARCHAR2
    IS
    msg_rec msg_info%ROWTYPE := msgrow (code_in, type_in);
    BEGIN
    IF msg_rec.msgtext IS NULL AND use_sqlerrm
    THEN
    msg_rec.msgtext := SQLERRM (code_in);
    END IF;

    RETURN msg_rec.msgtext;
    END;

    FUNCTION NAME (code_in IN INTEGER, type_in IN VARCHAR2)
    RETURN VARCHAR2
    IS
    msg_rec msg_info%ROWTYPE := msgrow (code_in, type_in);
    BEGIN
    RETURN msg_rec.msgname;
    END;

    PROCEDURE genpkg (
    NAME_IN IN VARCHAR2
    , oradev_use IN BOOLEAN := FALSE
    , to_file_in IN BOOLEAN := TRUE
    , dir_in IN VARCHAR2 := 'DEMO'
    , ext_in IN VARCHAR2 := 'pkg'
    )
    IS
    CURSOR exc_20000
    IS
    SELECT *
    FROM msg_info
    WHERE msgcode BETWEEN -20999 AND -20000 AND msgtype = 'EXCEPTION';

    -- Send output to file or screen?
    v_to_screen BOOLEAN := NVL (NOT to_file_in, TRUE);
    v_file VARCHAR2 (1000) := name_in || '.' || ext_in;

    -- Array of output for package
    TYPE lines_t IS TABLE OF VARCHAR2 (1000)
    INDEX BY BINARY_INTEGER;

    output lines_t;

    -- Now pl simply writes to the array.
    PROCEDURE pl (str IN VARCHAR2)
    IS
    BEGIN
    output (NVL (output.LAST, 0) + 1) := str;
    END;

    -- Dump to screen or file.
    PROCEDURE dump_output
    IS
    BEGIN
    IF v_to_screen
    THEN
    FOR indx IN output.FIRST .. output.LAST
    LOOP
    DBMS_OUTPUT.put_line (output (indx));
    END LOOP;
    ELSE
    -- Send output to the specified file.
    DECLARE
    fid UTL_FILE.file_type;
    BEGIN
    fid := UTL_FILE.fopen (dir_in, v_file, 'W');

    FOR indx IN output.FIRST .. output.LAST
    LOOP
    UTL_FILE.put_line (fid, output (indx));
    END LOOP;

    UTL_FILE.fclose (fid);
    EXCEPTION
    WHEN OTHERS
    THEN
    DBMS_OUTPUT.put_line ( 'Failure to write output to '
    || dir_in
    || '/'
    || v_file
    );
    UTL_FILE.fclose (fid);
    END;
    END IF;
    END dump_output;
    BEGIN
    /* Simple generator, based on DBMS_OUTPUT. */
    pl ('CREATE OR REPLACE PACKAGE ' || NAME_IN);
    pl ('IS ');

    FOR msg_rec IN exc_20000
    LOOP
    IF exc_20000%ROWCOUNT > 1
    THEN
    pl (' ');
    END IF;

    pl (' exc_' || msg_rec.msgname || ' EXCEPTION;');
    pl ( ' en_'
    || msg_rec.msgname
    || ' CONSTANT INTEGER := '
    || msg_rec.msgcode
    || ';'
    );
    pl ( ' PRAGMA EXCEPTION_INIT (exc_'
    || msg_rec.msgname
    || ', '
    || msg_rec.msgcode
    || ');'
    );

    IF oradev_use
    THEN
    pl (' FUNCTION ' || msg_rec.msgname || ' RETURN INTEGER;');
    END IF;
    END LOOP;

    pl ('END ' || NAME_IN || ';');
    pl ('/');

    IF oradev_use
    THEN
    pl ('CREATE OR REPLACE PACKAGE BODY ' || NAME_IN);
    pl ('IS ');

    FOR msg_rec IN exc_20000
    LOOP
    pl (' FUNCTION ' || msg_rec.msgname || ' RETURN INTEGER');
    pl (' IS BEGIN RETURN en_' || msg_rec.msgname || '; END;');
    pl (' ');
    END LOOP;

    pl ('END ' || NAME_IN || ';');
    pl ('/');
    END IF;

    dump_output;
    END;
    END;
    /

    /* Sample data to be used in package generation. */

    BEGIN
    INSERT INTO msg_info
    VALUES (-20100, 'EXCEPTION', 'Balance too low', 'bal_too_low'
    , 'Description');
    INSERT INTO msg_info
    VALUES (-20200, 'EXCEPTION', 'Employee too young', 'emp_too_young'
    , 'Description');

    COMMIT;
    END;
    /

    关于Oracle raise_application_error 错误号最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36295233/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com