Skip to Main Content

SQL & PL/SQL

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Get SQL Text that Instered or Updated a Row

Sky13May 20 2013 — edited May 23 2013
Hello,
I am trying to get the SQL Test that is ether inserting or updating a row in one of my tables. We are finding rows with an DATETIMEIN column value greater then the DATERECORDED (sysdate). I could put a check constraint on the table to block such rows but this will cause an error and I am not sure what the application will do. I need to be as benign as possible.

I am trying to create a trigger on the table that will grab the SQL Text and maybe give us a clue how this is happening. I have tried a number of approaches and this code represents the two best I have come up with. However nether are the great. Option #1 never seems to get the correct SQL Text because of other triggers on the table I think. Option #2 gets the SQL but I am not confident it will get the SQL from the session that did the DDL on the table and fired the trigger as this is a real time and have many sessions posting to this table.

Any ideas would be great. I could even be going after this completely wrong and am open to any other ideas.

The Oracle version is 10.2.0.4.
create or replace 
trigger EVENTLOG_FUTURE_DATE_TRAP
after insert or update on EVENTLOG
for each row
declare
  vMsg VARCHAR2(4000);
  vSQL VARCHAR2(4000);
begin

if :NEW.DATETIMEIN > (sysdate + .1) then

/* Option #1 */
    select 
      replace(trim('~' from max(sys_connect_by_path(SQL_TEXT,'~')) keep (dense_rank last order by CURR)),'~','') as FULL_SQL_TEXT -- Works
    into
      vSQL
    from
      (
      select 
          S.USERNAME, S.SID as CURRENT_SID, S.SERIAL#, T.PIECE,
          T.SQL_TEXT,
          ROW_NUMBER() over (partition by S.USERNAME, S.SID, S.SERIAL# order by T.PIECE) as CURR,
          ROW_NUMBER() over (partition by S.USERNAME, S.SID, S.SERIAL# order by T.PIECE) -1 as PREV
      from 
        V$SESSION S,
        V$SQLTEXT_WITH_NEWLINES T
      where 
        S.SQL_ID is not null
        and S.PREV_SQL_ID = T.SQL_ID
        and S.SID = sys_context('USERENV','SID')
      order by 
        T.PIECE
      )
    connect by PREV = prior CURR
    start with CURR = 1; 


/* Option #2 */
/*    if INSERTING then
      select SQL_FULLTEXT into vSQL from (
      select * from V$SQLAREA where upper(SQL_FULLTEXT) like 'INSERT%PTNRATING%' order by LAST_LOAD_TIME desc)
      where rownum = 1; 
    else
      select SQL_FULLTEXT into vSQL from (
      select * from V$SQLAREA where upper(SQL_FULLTEXT) like 'UPDATE%PTNRATING%' order by LAST_LOAD_TIME desc)
      where rownum = 1; 
    end if;    
    vSQL := substr(vSQL,1,1024);
*/    
    select
      'HOST: ' || SYS_CONTEXT('USERENV', 'HOST') || ' | ' ||
      'OS_USER: ' || SYS_CONTEXT('USERENV', 'OS_USER')  || ' | ' ||
      'SESSION_USER: ' || SYS_CONTEXT('USERENV', 'SESSION_USER')  || ' | ' ||
      'IP_ADDRESS: ' || SYS_CONTEXT('USERENV', 'IP_ADDRESS')  || ' | ' ||
      'TERMINAL: ' || SYS_CONTEXT('USERENV', 'TERMINAL')  || ' | ' ||
--  set through the DBMS_APPLICATION_INFO package
      'CLIENT_IDENTIFIER: ' || SYS_CONTEXT('USERENV', 'CLIENT_IDENTIFIER') || ' | ' ||
      'CLIENT_INFO: ' || SYS_CONTEXT('USERENV', 'CLIENT_INFO') || ' | ' ||      
      'MODULE: ' || SYS_CONTEXT('USERENV', 'MODULE') || ' | ' ||
      'ACTION: ' || SYS_CONTEXT('USERENV', 'ACTION') 
    into 
      vMsg
    from 
      dual;
    vMsg := 'EVENTLOGID: ' || :NEW.EVENTLOGID || 
    ' | ' || 'OLD.DATETIMEIN: ' || to_char(:OLD.DATETIMEIN,'MM/DD/YYYY HH:MIPM') || ' | ' || 'NEW.DATETIMEIN: ' || to_char(:NEW.DATETIMEIN,'MM/DD/YYYY HH:MIPM') || 
    ' | ' || 'OLD.DATETIMEOUT: ' || to_char(:OLD.DATETIMEOUT,'MM/DD/YYYY HH:MIPM') || ' | ' || 'NEW.DATETIMEOUT: ' || to_char(:NEW.DATETIMEOUT,'MM/DD/YYYY HH:MIPM') || 
    ' | ' || vMsg; 
    vMsg := substr(vMsg,1,1024);

   insert into EVENTLOG_DEBUG 
      (DEBUGID, 
      PROC, 
      VALUES_IN, 
      VALUES_OUT)
		values 
      (SEQ_DEBUG.NEXTVAL, 
      'eventlog_future_date_trap',
      vMsg,
      vSQL);
  end if;      
end;
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Jun 20 2013
Added on May 20 2013
13 comments
546 views