2009-11-10 8 views
9

Ich habe die folgende Abfrage geschrieben, um die letzte ausgeführte SQL-Anweisung in der Oracle-Datenbank für eine bestimmte Sitzung zu erhalten. Der SQL-Text enthält nicht den tatsächlichen Wert der Bindungsvariablen. Wie erhält man die Werte der Bindevariablen zusammen mit dem SQL-Text?Wie bekomme ich die zuletzt ausgeführte SQL-Anweisung und binde Variablenwerte in Oracle?

SELECT * FROM v$SQLTEXT_WITH_NEWLINES WHERE address = 
    (SELECT prev_sql_addr FROM v$session WHERE audsid = userenv('SESSIONID')) 
ORDER BY piece; 

Antwort

5

Ich glaube nicht, dass die Bindevariablen Werte standardmäßig gespeichert werden. Abgesehen von den potenziellen Sicherheitsproblemen (da die Arbeit anderer Sitzungen tatsächlich stattfindet) wäre die Menge der zu speichernden Daten sehr groß.

Wenn Sie die Werte der Bind-Variablen sehen möchten, sollten Sie den Trace für diese Sitzung aktivieren. Sie würden dies tun, indem Sie den folgenden Befehl in der Sitzung ausgeführt wird:

alter session set events '10046 trace name context forever, level 12'; 

Mehr Informationen über AskTom: 10046 tracing

+3

Die späteren Versionen (10g und 11g) tun, um die Bindungsvariablen für spähen in V $ SQL_BIND_capture verwendet aufzeichnen. Aber das wird nur für die Optimierungsphase des Parse dieses SQL sein, nicht für jede Ausführung. –

+0

@GaryMyers Könnten Sie eine Referenz dafür bereitstellen? – AHungerArtist

20

Um die Bindungsvariablen erhalten Sie den Code unten verwenden müssen, müssen Sie nicht Tracing verwenden müssen.

SELECT * FROM v$sql_bind_capture WHERE sql_id=''; 

oder

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

+1 http://download.oracle.com/docs/cd/B19306_01/server.102/b14237/dynviews_2114.htm Aber STATISTICS_LEVEL Server-Initialisierung Parameter über BASIC sein muss. – ThinkJet

3

, wenn Sie in sqlplus sind, können Sie

select * from table (dbms_xplan.display_cursor (null,null, 'ADVANCED'));

ausführen oder wenn Sie für SQL von jemandem ausgeführt suchen sonst nur setzen in ihrer die SQL_ID und untergeordneten Cursor #:

select * from table (dbms_xplan.display_cursor ('sql_id',child_cursor#, 'ADVANCED'));

wie in

select * from table (dbms_xplan.display_cursor ('a18asdr99x',0, 'ADVANCED'));

diese Methode das einzige zeigt spähte Bindevariablen zeigt. Die einzige zuverlässige Art und Weise wird Tracing mit Bind-Variablen

dbms_monitor.session_trace_enable(session_id => 127, serial_num => 29, waits => FALSE, binds => TRUE)

aber natürlich, die getan werden muss, bevor die Abfrage

2

Führen Sie die unten Abfrage ausgeführt wird, die die sql_id als Eingabeparameter und gibt die Ausgabe mit ersetzten Bind-Variablenwerten.

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; 
/
Verwandte Themen