|
| 1 | +create or replace package body ords_trc_pkg |
| 2 | +is |
| 3 | + |
| 4 | + procedure snapshot(p_username varchar2 := null) |
| 5 | + is |
| 6 | + v_plan clob := ''; |
| 7 | + v_entries number(10) := 0; |
| 8 | + begin |
| 9 | + for r1 in (select * |
| 10 | + from gv$session |
| 11 | + where program = 'Oracle REST Data Services' |
| 12 | + and username <> 'ORDS_PUBLIC_USER' |
| 13 | + and username = nvl(upper(p_username),username)) loop |
| 14 | + |
| 15 | + -- sql_id |
| 16 | + if r1.sql_id is not null then |
| 17 | + select count(*) |
| 18 | + into v_entries |
| 19 | + from ords_trc_tab |
| 20 | + where inst_id = r1.inst_id |
| 21 | + and sid = r1.sid |
| 22 | + and serial# = r1.serial# |
| 23 | + and sql_id = r1.sql_id; |
| 24 | + |
| 25 | + if v_entries = 0 then |
| 26 | + for r2 in (select * from dbms_xplan.display_cursor(r1.sql_id)) loop |
| 27 | + v_plan := v_plan || r2.plan_table_output || chr(10); |
| 28 | + end loop; |
| 29 | + |
| 30 | + insert into ords_trc_tab |
| 31 | + (inst_id,sid,serial#,username,command,sql_exec_start,sql_id,sql_plan) |
| 32 | + values |
| 33 | + (r1.inst_id,r1.sid,r1.serial#,r1.username,r1.command,r1.sql_exec_start,r1.sql_id,v_plan); |
| 34 | + end if; |
| 35 | + end if; |
| 36 | + -- prev_sql_id |
| 37 | + if r1.prev_sql_id is not null then |
| 38 | + select count(*) |
| 39 | + into v_entries |
| 40 | + from ords_trc_tab |
| 41 | + where inst_id = r1.inst_id |
| 42 | + and sid = r1.sid |
| 43 | + and serial# = r1.serial# |
| 44 | + and sql_id = r1.prev_sql_id; |
| 45 | + |
| 46 | + if v_entries = 0 then |
| 47 | + for r2 in (select * from dbms_xplan.display_cursor(r1.prev_sql_id)) loop |
| 48 | + v_plan := v_plan || r2.plan_table_output || chr(10); |
| 49 | + end loop; |
| 50 | + |
| 51 | + insert into ords_trc_tab |
| 52 | + (inst_id,sid,serial#,username,command,sql_exec_start,sql_id,sql_plan) |
| 53 | + values |
| 54 | + (r1.inst_id,r1.sid,r1.serial#,r1.username,r1.command,r1.prev_exec_start,r1.prev_sql_id,v_plan); |
| 55 | + end if; |
| 56 | + end if; |
| 57 | + end loop; |
| 58 | + commit; |
| 59 | + end; |
| 60 | + |
| 61 | + procedure create_job(freq integer, p_username varchar2 := null) |
| 62 | + is |
| 63 | + v_job varchar2(200) := 'ORDS_TRC_JOB'; |
| 64 | + v_block varchar2(200) := 'BEGIN ORDS_TRC_PKG.SNAPSHOT'; |
| 65 | + n_of_jobs number(10); |
| 66 | + begin |
| 67 | + if p_username is not null then |
| 68 | + v_job := v_job || '_' || upper(p_username); |
| 69 | + v_block := v_block || '(''' ||upper(p_username)||''')'; |
| 70 | + end if; |
| 71 | + v_block := v_block||'; END;'; |
| 72 | + |
| 73 | + select count(*) |
| 74 | + into n_of_jobs |
| 75 | + from user_scheduler_jobs |
| 76 | + where job_name = v_job; |
| 77 | + |
| 78 | + if n_of_jobs <> 0 then |
| 79 | + raise_application_error(-20001,'You cannot trace the same database user in more than one job'); |
| 80 | + end if; |
| 81 | + |
| 82 | + dbms_scheduler.create_job(v_job, |
| 83 | + 'PLSQL_BLOCK', |
| 84 | + v_block, |
| 85 | + enabled => true, |
| 86 | + repeat_interval => 'FREQ=SECONDLY;INTERVAL='||freq); |
| 87 | + end; |
| 88 | + |
| 89 | + procedure drop_job(p_username varchar2 := null) |
| 90 | + is |
| 91 | + v_job varchar2(200) := 'ORDS_TRC_JOB'; |
| 92 | + begin |
| 93 | + if p_username is not null then |
| 94 | + v_job := v_job || '_' || upper(p_username); |
| 95 | + end if; |
| 96 | + |
| 97 | + dbms_scheduler.drop_job(v_job,defer => true); |
| 98 | + end; |
| 99 | + |
| 100 | + function get_report (p_username varchar2 := null) return clob |
| 101 | + is |
| 102 | + v_rep clob := ''; |
| 103 | + v_command varchar2(200); |
| 104 | + prev_username varchar2(30) := ' '; |
| 105 | + prev_session varchar2(200):= ' '; |
| 106 | + begin |
| 107 | + for r in (select * |
| 108 | + from ords_trc_tab |
| 109 | + where username = nvl(upper(p_username),username) |
| 110 | + order by username, inst_id, sid, serial#, sql_exec_start, sql_id ) loop |
| 111 | + if prev_username <> r.username then |
| 112 | + -- start of new user section |
| 113 | + prev_username := r.username; |
| 114 | + v_rep := v_rep||chr(10)|| |
| 115 | + ' USERNAME : '||r.username ||chr(10)|| |
| 116 | + '======================================================'||chr(10); |
| 117 | + end if; |
| 118 | + |
| 119 | + if prev_session <> r.inst_id||':'||r.sid||':'||r.serial# then |
| 120 | + -- start of new sid section |
| 121 | + prev_session := r.inst_id||':'||r.sid||':'||r.serial#; |
| 122 | + v_rep := v_rep || chr(10) || |
| 123 | + 'inst_id:sid:serial# : ' || prev_session || chr(10) || |
| 124 | + '-----------------------------------------------------' || chr(10); |
| 125 | + end if; |
| 126 | + |
| 127 | + select command_name |
| 128 | + into v_command |
| 129 | + from v$sqlcommand |
| 130 | + where command_type = r.command; |
| 131 | + |
| 132 | + v_rep := v_rep || chr(10) || |
| 133 | + 'command type : '||r.command||' ('||v_command||')'||chr(10)|| |
| 134 | + 'plan : '||chr(10) || |
| 135 | + r.sql_plan || chr(10); |
| 136 | + end loop; |
| 137 | + return v_rep; |
| 138 | + end; |
| 139 | + |
| 140 | + procedure print_report(p_username varchar2 := null) |
| 141 | + is |
| 142 | + v_report clob := get_report(p_username); |
| 143 | + begin |
| 144 | + dbms_output.put_line(v_report); |
| 145 | + end; |
| 146 | + |
| 147 | + procedure purge_logs(p_username varchar2 := null) |
| 148 | + is |
| 149 | + begin |
| 150 | + delete from ords_trc_tab |
| 151 | + where username = nvl(upper(p_username),username); |
| 152 | + |
| 153 | + commit; |
| 154 | + end; |
| 155 | +end; |
| 156 | +/ |
0 commit comments