2

有没有办法跟踪使用 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_id 的 sql 被覆盖。

4

1 回答 1

3

捕获所有绑定变量的唯一方法是在每次执行时执行硬解析。实现此目的的简单方法是在游标执行后从堆中清除游标,如下所示:

-- 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#CHDCBEBB

之后,您可以依靠 v$sql_bind_capture 来映射绑定变量。

于 2013-10-19T17:33:56.280 回答