oracle中如何获取最后执行的SQL语句并绑定变量值
Posted
技术标签:
【中文标题】oracle中如何获取最后执行的SQL语句并绑定变量值【英文标题】:How to get the last executed SQL statement and bind variable values in oracle 【发布时间】:2009-11-10 11:28:24 【问题描述】:我编写了以下查询来获取特定会话在 oracle 数据库中最后执行的 SQL 语句。 SQL 文本不包含绑定变量的实际值。如何获取绑定变量值以及 SQL 文本。
SELECT * FROM v$SQLTEXT_WITH_NEWLINES WHERE address =
(SELECT prev_sql_addr FROM v$session WHERE audsid = userenv('SESSIONID'))
ORDER BY piece;
【问题讨论】:
【参考方案1】:要获取绑定变量,您必须使用下面的代码,您不需要使用跟踪。
SELECT * FROM v$sql_bind_capture WHERE sql_id='';
或
SELECT NAME,POSITION,DATATYPE_STRING,VALUE_STRING
FROM v$sql_bind_capture WHERE sql_id='';
http://shaharear.blogspot.com/2009/02/find-bind-variable-value.html
【讨论】:
+1 download.oracle.com/docs/cd/B19306_01/server.102/b14237/… 但 STATISTICS_LEVEL 服务器初始化参数必须高于 BASIC。【参考方案2】:我认为默认情况下不会存储绑定变量值。不考虑潜在的安全问题(查看其他会话的实际工作),要存储的数据量将是巨大的。
如果您想查看绑定变量的值,您应该激活该会话的跟踪。您可以通过在该会话中执行以下命令来做到这一点:
alter session set events '10046 trace name context forever, level 12';
更多关于AskTom: 10046 tracing的信息
【讨论】:
以后的版本(10g 和 11g)确实在 V$SQL_BIND_capture 中记录了用于 peeking 的绑定变量。但这仅适用于该 SQL 解析的优化阶段,而不是每次执行。 @GaryMyers 你能提供一个参考吗?【参考方案3】:如果你在sqlplus你可以执行
select * from table
( dbms_xplan.display_cursor (null,null, 'ADVANCED'));
或者如果您正在寻找其他人执行的 SQL,只需输入他们的 SQL_ID 和子游标#:
select * from table
( dbms_xplan.display_cursor ('sql_id',child_cursor#, 'ADVANCED'));
如
select * from table
( dbms_xplan.display_cursor ('a18asdr99x',0, 'ADVANCED'));
这个方法只显示了被偷看的绑定变量。唯一可靠的方法是使用绑定变量进行跟踪
dbms_monitor.session_trace_enable(session_id => 127,
serial_num => 29,
waits => FALSE,
binds => TRUE)
当然,这必须在查询执行之前完成
【讨论】:
【参考方案4】:运行以下查询,该查询将 sql_id 作为输入参数,并将使用替换的绑定变量值给出输出。
set serveroutput on;
DECLARE
v_fulltext CLOB;
v_sql_id VARCHAR2 (100);
CURSOR c1( v_sql_id varchar2)
IS
SELECT decode(substr(NAME,1,4),':SYS',replace(name,':',':"')||'"' ,NAME ) NAME, POSITION, datatype_string,nvl(VALUE_STRING,'NULL') value_string
FROM v$sql_bind_capture
WHERE sql_id = v_sql_id;
BEGIN
v_sql_id:= '&sql_id';
SELECT sql_fulltext
INTO v_fulltext
FROM v$sql
WHERE sql_id =v_sql_id AND ROWNUM = 1;
FOR rec IN c1(v_sql_id)
LOOP
IF substr(rec.datatype_string,1,8) = 'VARCHAR2'
THEN
SELECT REPLACE (v_fulltext,
rec.NAME,
'''' || rec.value_string || ''''
)
INTO v_fulltext
FROM DUAL;
END IF;
IF rec.datatype_string = 'NUMBER'
THEN
SELECT REPLACE (v_fulltext, rec.NAME, rec.value_string)
INTO v_fulltext
FROM DUAL;
END IF;
END LOOP;
DBMS_OUTPUT.PUT_LINE(v_fulltext);
EXCEPTION
WHEN NO_DATA_FOUND
THEN DBMS_OUTPUT.PUT_LINE('NO SQL FOUND FOR THE SQL ID');
END;
/
【讨论】:
这对我不起作用 - 最后一个绑定变量没有被替换。【参考方案5】:查看 BiPin 的答案,我对其进行了一些修改以满足我的需要。 我需要弄清楚用户在实时运行报告时使用了哪些参数。这是我的解决方案,它将子编号添加到 v$sql_bind_capture 的查询中。
declare
v_sql_id varchar(100);
v_fulltext clob;
v_childnumber number;
begin
v_sql_id := '&sql_id';
v_childnumber := '&childnumber';
SELECT LISTAGG(SQL_text, '') within group (order by piece)
INTO v_fulltext
FROM v$sqltext
WHERE sql_id =v_sql_id;
for I in (select name,VALUE_STRING from v$sql_bind_capture where sql_id = V_SQL_ID and child_number = V_CHILDNUMBER)LOOP
v_fulltext := regexp_replace(v_fulltext,i.name||' ',i.value_string);
end LOOP;
DBMS_OUTPUT.PUT_LINE(v_fulltext);
end;
【讨论】:
以上是关于oracle中如何获取最后执行的SQL语句并绑定变量值的主要内容,如果未能解决你的问题,请参考以下文章