Search notes:

Oracle: Identify statements that were executed against tables in a given schema

This is an attempt to use Oracle's AWR to identify SQL statements that were executed against tables in a given schema.
drop   table tq84_find_stmts_sql_plan purge;

create table tq84_find_stmts_sql_plan as
select
   count(*)          cnt,
   sql_id,
   dbid
from
   dba_hist_sql_plan
where
   object_owner in (…)
group by
   sql_id,
   dbid;

select
   fnd.sql_id,
   txt.sql_text
from
   tq84_find_stmts_sql_plan fnd                                                       left join
   dba_hist_sqltext         txt on fnd.sql_id = txt.sql_id and fnd.dbid = txt.dbid
where
    txt.sql_text is not null
;

Python script to find statements in multiple databases over a longer period of time

This Python script uses the cx_Oracle library to extract SQL statements executed against tables in a given schema from multiple databases.
For every SQL_ID the script finds, it writes an SQL file whose name correponds to the SQL_ID in the subdirectory named extracted-statements (which must first be created).
Thus, the script can be run multiple times over a longer period than the retention period of AWR.
from pathlib import Path
import cx_Oracle as cxora
 
sel_stmt = '''
select
   sql_id,
   sql_text
from (
   select
      p.sql_id,
      t.sql_text,
      row_number() over (partition by p.sql_id order by 'x') rn
   from (
        select distinct
           p.sql_id
        from
           dba_hist_sql_plan p
        where
           p.object_owner in ('DWH_DM_ABS', 'SBXSABS', 'SBXMABS')
   ) p join
   dba_hist_sqltext t on t.sql_id = p.sql_id
)
where
   rn = 1
'''
 
 
 
def create_or_skip_file(sql_id, content) -> str:
 
    filename = f'extracted-statements/{sql_id}.sql'
 
    if Path(filename).exists():
       print(f'{sql_id} already extracted')
       return
 
    Path(filename).touch()
    print(f'{sql_id} newly extracted')
   
    with open(filename, 'w') as file:
        file.write(content)
   
 
def db(user, dsn):
 
    con = cxora.connect(user=user, dsn=dsn)
 
    cur = con.cursor()
    global sel_stmt
    cur.execute(sel_stmt)
    for sql_id, stmt_clob in cur:
        stmt = stmt_clob.read()
        create_or_skip_file(sql_id, stmt)
 
 
if True:
   db('[rene]', 'abc1' )
   db('[rene]', 'def1' )
   db('[test]', 'testa')
   db('[test]', 'testb')
See also: Using cx_Oracle to execute an SQL statement in many databases and print the result with tabulate.

Index

Fatal error: Uncaught PDOException: SQLSTATE[HY000]: General error: 8 attempt to write a readonly database in /home/httpd/vhosts/renenyffenegger.ch/php/web-request-database.php:78 Stack trace: #0 /home/httpd/vhosts/renenyffenegger.ch/php/web-request-database.php(78): PDOStatement->execute(Array) #1 /home/httpd/vhosts/renenyffenegger.ch/php/web-request-database.php(30): insert_webrequest_('/notes/developm...', 1758206762, '216.73.216.150', 'Mozilla/5.0 App...', NULL) #2 /home/httpd/vhosts/renenyffenegger.ch/httpsdocs/notes/development/databases/Oracle/installed/data-dictionary/hist/_queries/statements-on-tables-in-given-schema(131): insert_webrequest() #3 {main} thrown in /home/httpd/vhosts/renenyffenegger.ch/php/web-request-database.php on line 78