If you don’t have access to filesystem or love to do everything in SQL here is the quick and dirty solution how to extract information about ORA-00060 from Oracle trace files.
I’m to lazy to write a normal script with variables thus just add the comments in the code
-- Get trace files dir
SELECT VALUE FROM v$diag_info WHERE NAME = 'Diag Trace';
-- create directory object for trace files dir
CREATE DIRECTORY test_trace_dir AS '&VALUE_FROM_PREVIOUS_STEP';
-- file to clob extractor procedure was found in stackoverflow
CREATE OR REPLACE FUNCTION test_trace_read(p_file_name IN VARCHAR2) RETURN CLOB AS
l_clob CLOB;
l_bfile BFILE;
dst_offset NUMBER := 1;
src_offset NUMBER := 1;
lang_ctx NUMBER := dbms_lob.default_lang_ctx;
warning NUMBER;
BEGIN
l_bfile := bfilename('TEST_TRACE_DIR', p_file_name);
dbms_lob.fileopen(l_bfile);
dbms_lob.createtemporary(l_clob, TRUE);
dbms_lob.loadclobfromfile(dest_lob => l_clob,
src_bfile => l_bfile,
amount => dbms_lob.getlength(l_bfile),
dest_offset => dst_offset,
src_offset => src_offset,
bfile_csid => dbms_lob.default_csid,
lang_context => lang_ctx,
warning => warning);
dbms_lob.fileclose(l_bfile);
RETURN l_clob;
END;
/
-- query to return piece of tracefile
-- full tracefile content can be returned as well
-- number of rows is specified in variable
WITH traces AS (
SELECT t.originating_timestamp, t.module_id, t.message_text,
regexp_replace(t.message_text, '.*More info in file (.*)\.$', '\1') full_file_name,
regexp_replace(t.message_text, '.*More info in file .*\/(.*)\.\s*$', '\1') file_name -- related from message format!
FROM V$DIAG_ALERT_EXT t
WHERE message_text LIKE '%ORA-00060%'
ORDER BY 1 DESC
),
trace_files AS (
SELECT test_trace_read(file_name) CONTENT, t.*
FROM traces t
WHERE ROWNUM <= &NUM_ROWS
)
SELECT SUBSTR(CONTENT, INSTR(CONTENT, 'Deadlock graph:'), INSTR(CONTENT, '----- Call Stack Trace -----') - INSTR(CONTENT, 'Deadlock graph:')) substr_trace,
t.originating_timestamp, t.module_id, t.full_file_name, t.message_text
FROM trace_files t
;