Проверьте dbms_sql.execute исполняемый код PL/SQL

Есть ли способ отследить, какой код был выполнен с использованием dbms_sql.execute?

Например, если я запускаю этот запрос:

DECLARE
    cursor_name INTEGER;
    rows_processed INTEGER;
BEGIN
    cursor_name := dbms_sql.open_cursor;
    DBMS_SQL.PARSE(cursor_name, 'SELECT * FROM dual WHERE 2 = :x' ,DBMS_SQL.NATIVE);
    DBMS_SQL.BIND_VARIABLE(cursor_name, ':x', 2);
    rows_processed := DBMS_SQL.EXECUTE(cursor_name);
    DBMS_SQL.CLOSE_CURSOR(cursor_name);   
EXCEPTION
WHEN OTHERS THEN
    DBMS_SQL.CLOSE_CURSOR(cursor_name);
END;

Я должен быть в состоянии найти результат:

SELECT * FROM dual WHERE 2 = 2

Я попытался посмотреть в v$sql/v$sql_bind_capture и dba_hist_sqltext/dba_hist_sqlbind, но это кажется ненадежным, поскольку при запуске одного и того же sql с разными переменными связывания перезаписывается sql с тем же sql_id.

1 ответ

Решение

Единственный способ перехватить все переменные связывания - выполнить хард-анализ при каждом выполнении. Самый простой способ добиться этого - очистить курсор от кучи после его выполнения следующим образом:

-- get sqlAddr and hashVal from v$sqlarea
SYS.dbms_shared_pool.purge(SqlAddr||', '||hashVal,'c',127); -- 127 is a bitmask for heaps 0~7 to be freed

http://docs.oracle.com/cd/B28359_01/appdev.111/b28419/d_shared_pool.htm

После этого вы можете положиться на v$sql_bind_capture для отображения переменных связывания.

Другие вопросы по тегам