I know this might seem a simple question - for which you might think existing answers exist. However ...
Understand that I want it be reasonable in performance, so it allows to be logged for every single query executed - or at least the big ones - without much overhead.
My first idea was this query:
select sid,serial#,prev_sql_id from v$session where audsid=userenv('sessionid');
My idea was if I run this right after my target query, I will capture the correct sql_id
through prev_sql_id.
However ... I was not ... I was getting a different SQL ... apparently in between my target SELECT statement and the query for prev_sql_id
, something else ran. In my case Auditing is enabled, and I was capturing the insert into the SYS.AUD$
table. No good.
As my main purpose for this attempt was to capture the execution plan for the query (as it was executed and captured by the shared pool), I thought that instead I can simply run this query:
SELECT *
FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR());
Documentation states that with NULL
SQL_ID
as parameter, it will run the explain plan on the most recent query ran. I was hoping that this would take care of earlier issues. However ... I got the plan for the exact same insert into the SYS.AUD$
table.
You might say, ok, then just simply put a comment in your query that allows to easily capture the SQL_ID
, like in following:
SELECT /* SQL: 1234-12' */ FROM DUAL;
Then I can try to find the SQL_ID as follows:
SELECT * FROM V$SQLAREA WHERE sql_text like '%SQL: 1234-12%';
That will give me several possible candidates, of which the V$SQLAREA
query itself is also included. The problem here is that I will need to randomize every query ran, which would cause me to always have a hard-parse.
I have tried other solutions where I go through history, but that comes at a much bigger cost. I have tried to search other solutions. They all seem to lag in some way.
Related Articles: