Oracle automatically saves all executed sql statements

foreword

  A strange bug has occurred on the project, preventing the user from operating the system properly. Reflected on the data, a field (number type) of a table has become null for no reason. We searched for all the additions, deletions, changes, and inspection codes involved in the entire system, as well as storage, etc., but failed to find the reason, and finally decided to check All SQL executed in the database is checked one by one.

Embodiment 1

  The first is to use the v$sql view to query, but the data in this result set cannot be guaranteed to exist for a long time, and it cannot be migrated to a new server with the database.

select t.SQL_TEXT--varchar type sql (sql statements with more than 1000 characters will not be displayed)
      , t.SQL_FULLTEXT--clob type sql (complete sql statement)
      ,to_char(t.LAST_ACTIVE_TIME,'yyyy-mm-dd hh24:mi:ss')--sql execution time
from v$sql t
where t.PARSING_SCHEMA_NAME='SCOTT'--uppercase username
  and trunc(t.LAST_ACTIVE_TIME)=trunc(sysdate)--sql executed today
-- output in reverse time
order by 3 desc;
    PS related knowledge points (check it yourself): 

     The difference between v$sql, v$sqlarea and v$sqltext

     How long will the data in the view be retained?

Embodiment 2

   Regularly save the sql executed by the database to a separate table (of course, this table needs to be cleaned regularly). Considering the large amount of data in this table, open a separate table space:

create tablespace sqlarea--tablespace name is sqlarea
datafile '/opt/oracle/oradata/sqlarea.dbf'--database file path
size 128m--the initial size of the file
autoextend on--set file auto-growth
next 64m-- 64MB each time
maxsize 20480m--Maximum no more than 20GB
extent management local;
 
--Does not limit user operations on tablespaces
grant create session,create table,unlimited tablespace to SCOTT;
   After the tablespace is ready, you can create the table
create table sqltextlog(
       sql_text varchar2(1000),--text type sql
       sql_fulltext clob, --clb type sql
       action varchar2(64),--source of executing sql
       last_active_time date--execution time
)
--Specify the table space to be used. If you don't write it, it will go to the default table space. The newly created table space will be wasted.
tablespace sqlarea;
  Now you can insert data into the table. In order to allow the database to automatically insert data into the table, we encapsulate the insertion process into a stored procedure, and the name of the storage is PRO_SQLTextLog
create or replace procedure PRO_SQLTextLog is--save sql to the specified table
time_ date;--time variable, indicating the last time the data was inserted into the table
begin
  --Assign a value to the time variable, when the table is empty, the zero o'clock of the day is used by default
  select nvl(max(last_active_time),trunc(sysdate))
  into time_
  from sqltextlog;
  --Start inserting, the inserted data range is from the last insert time to the present
  insert into sqltextlog(sql_text,sql_fulltext,action,last_active_time)
  select sql_text,sql_fulltext,action,last_active_time
  from v$sql t
  where t.PARSING_SCHEMA_NAME='SCOTT'
    and t.LAST_ACTIVE_TIME>time_
    and t.LAST_ACTIVE_TIME<sysdate;
  --don't forget to submit
  commit;
end PRO_SQLTextLog; 
  One thing to note here is the access rights of v$sql, you need to execute the following SQL to solve the problem
grant select any dictionary to SCOTT;
  Now that the stored procedure is in place, the next step is to have Oracle execute the stored procedure every 10 minutes.
variable jobid number;--jobid to be used as output
begin
  --The first parameter, used as the output of the result
  --The second parameter is the storage to be executed, note that it is a string type, and there is an English semicolon at the end
  --The third parameter, the time when the job starts, if you want to start at 0:00 tomorrow, change it to trunc(sysdate)+1
  --The fourth parameter is the time of the next run, which is equivalent to the time interval. Note that it is a string type
  sys.dbms_job.submit(:jobid,'PRO_SQLTextLog;',sysdate,'sysdate+10/1440');
  commit;
end;
/
  The above sql should be executed under sqlplus, or in the Command Window of PL/SQL Developer. Note that the end is not an English semicolon, but a slash.   At this point, the function of Oracle automatically saving SQL to the specified database table is completed, and all executed SQL statements will appear in sqltextlog
select * from sqltextlog l order by l.last_active_time desc;
  The execution of the job can be viewed by executing the following sql
select job
      ,last_date
      ,next_date
      ,failures
      ,broken
from user_jobs;
   PS related knowledge points:

     create tablespace

     Specify the tablespace when creating a table

     create stored procedure

     JOB timed job

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326944086&siteId=291194637