PL/SQLで発生したエラー情報を記録したい

# Question

F001・F002・F003というFunctionがあり、F001がF002を呼び出し、F002がF003を呼び出すという構造になっています。

```SQL
CREATE OR REPLACE FUNCTION F001(i_key INT) RETURN INT IS
BEGIN
    RETURN F002(i_key);
END;


CREATE OR REPLACE FUNCTION F002(i_key INT) RETURN INT IS
BEGIN
    RETURN F003(i_key);
END;


CREATE OR REPLACE FUNCTION F003(i_key INT) RETURN INT IS
    v INT;
BEGIN
    SELECT value INTO v FROM TBL WHERE key = i_key;
    RETURN v;
END;
```

ここで、引数を99としてF001を呼び出したところ、F001がエラーになりました。このエラー情報をどこかに記録する方法はないでしょうか?


# Answer

まずはエラー情報を記録するためのテーブルを作成します。

```SQL
CREATE TABLE error_logs (
    message    VARCHAR2 (4000),
    backtrace  VARCHAR2 (4000),
    callstack  VARCHAR2 (4000),
    created_by TIMESTAMP
);
```

その後、エラーが発生する関数を呼び出します。このときException節にて、先ほど作成したテーブルにエラー情報をINSERTするようにします。

```SQL
DECLARE
    v INT;
BEGIN 
    v := F001(99);
EXCEPTION
    WHEN OTHERS THEN
        INSERT INTO error_logs (message, backtrace, callstack, created_by) VALUES (
            SYS.DBMS_UTILITY.FORMAT_ERROR_STACK,
            SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE,
            SYS.DBMS_UTILITY.FORMAT_CALL_STACK,
            SYSDATE
        );
        COMMIT;
END;
```

実行後、error_logsテーブルにエラー情報が記録されていることが確認できるはずです。


|MESSAGE                                                                                                                                            |BACKTRACE                                                                                                                     |CALLSTACK                                                                                                                                                                    |CREATED_BY         |
|:--------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------------|
|ORA-01403: データが見つかりません。<br>ORA-06512: "TS01.F003", 行4<br>ORA-06512: "TS01.F002", 行3<br>ORA-06512: "TS01.F001", 行3<br>|ORA-06512: "TS01.F003", 行4<br>ORA-06512: "TS01.F002", 行3<br>ORA-06512: "TS01.F001", 行3<br>ORA-06512: 行4<br>|----- PL/SQL Call Stack -----<br>  object      line  object<br>  handle    number  name<br>0x7c8063f0         1  anonymous block<br>0xad95e1c8         7  anonymous block<br>|2024/11/15 21:46:44|


# 環境

```SQL
SELECT * FROM v$version;
```

|BANNER                                                                |BANNER_FULL                                                                                  |BANNER_LEGACY                                                         |CON_ID|
|:---------------------------------------------------------------------|:--------------------------------------------------------------------------------------------|:---------------------------------------------------------------------|-----:|
|Oracle Database 19c Standard Edition 2 Release 19.0.0.0.0 - Production|Oracle Database 19c Standard Edition 2 Release 19.0.0.0.0 - Production<br>Version 19.19.0.0.0|Oracle Database 19c Standard Edition 2 Release 19.0.0.0.0 - Production|     0|