A PL/SQL Program – After many many years!

Wrote a little pl/sql program after several years… glad it worked as expected… thought of sharing the code, might be useful for someone out there…

The requirement is to drop tables that are older than 60 days from a schema named CR_BKUP periodically. Did not want to just drop the tables, so taking a backup of the whole schema using data pump api and then dropping the tables. The table names dropped are also written to a log file. The code is created as a procedure, so that I can schedule it using the database scheduler.

If I am violating any coding standards or a better way to accomplish the result, please let me know.

This code is also a quick demonstration of how to use DBMS_DATAPUMP and UTL_FILE programs.

 

/* Formatted */
CREATE OR REPLACE PROCEDURE XX_DROP_CR_BKUP_TABLES (
   threshold_days NUMBER DEFAULT 60)
IS
   /******************************************************************************
      NAME:       XX_DROP_CR_BKUP_TABLES
      PURPOSE:    Drop tables under CR_BKUP schema older than 60 days

   ******************************************************************************/

   CURSOR tablist
   IS
      SELECT owner || '.' || object_name table_name
        FROM dba_objects
       WHERE     owner = 'CR_BKUP'
             AND object_type = 'TABLE'
             AND last_ddl_time < (SYSDATE - threshold_days);

   log_file   UTL_FILE.FILE_TYPE;
BEGIN
   -- Export all the tables belonging to CR_BKUP schema to file system
   -- This dump file will be overwritten next time the job runs
   -- OS file backup will copy to the backup media
   DECLARE
      dp_file   NUMBER;
      jstatus   VARCHAR2 (200);
      ltmp      VARCHAR2 (200);
   BEGIN
      EXECUTE IMMEDIATE
         'CREATE OR REPLACE DIRECTORY CR_BKUP_DIR AS ''/u01/app/oracle/expdp''';

      BEGIN
         SELECT table_name
           INTO ltmp
           FROM user_tables
          WHERE table_name = 'CR_BKUP_TABLE_EXP';

         EXECUTE IMMEDIATE 'DROP TABLE CR_BKUP_TABLE_EXP';
      EXCEPTION
         WHEN NO_DATA_FOUND
         THEN
            NULL;
      END;

      --utl_file.fremove( 'CR_BKUP_DIR', 'cr_bkup_tabs.dmp' );
      --utl_file.fremove( 'CR_BKUP_DIR', 'cr_bkup_tabs.log' );

      dp_file :=
         DBMS_DATAPUMP.open (OPERATION   => 'EXPORT',
                             JOB_MODE    => 'SCHEMA',
                             JOB_NAME    => 'CR_BKUP_TABLE_EXP');

      DBMS_DATAPUMP.add_file (
         HANDLE      => dp_file,
         FILENAME    => 'cr_bkup_tabs.dmp',
         DIRECTORY   => 'CR_BKUP_DIR',
         FILETYPE    => DBMS_DATAPUMP.KU$_FILE_TYPE_DUMP_FILE,
         REUSEFILE   => 1);
      DBMS_DATAPUMP.add_file (
         HANDLE      => dp_file,
         FILENAME    => 'cr_bkup_tabs.log',
         DIRECTORY   => 'CR_BKUP_DIR',
         FILETYPE    => DBMS_DATAPUMP.KU$_FILE_TYPE_LOG_FILE);
      DBMS_DATAPUMP.metadata_filter (HANDLE   => dp_file,
                                     NAME     => 'SCHEMA_LIST',
                                     VALUE    => '''CR_BKUP''');
      DBMS_DATAPUMP.start_job (HANDLE => dp_file);
      DBMS_DATAPUMP.wait_for_job (HANDLE => dp_file, JOB_STATE => jstatus);
      DBMS_DATAPUMP.detach (HANDLE => dp_file);
   EXCEPTION
      WHEN OTHERS
      THEN
         DBMS_DATAPUMP.detach (HANDLE => dp_file);
         RAISE;
   END;

   -- Export completed, now drop the tables older than the create date threshold
   --
   log_file := UTL_FILE.FOPEN ('CR_BKUP_DIR', 'cr_bkup_table_drop.txt', 'W');
   UTL_FILE.put_line (log_file,
                      'The following tables dropped on ' || SYSTIMESTAMP);

   FOR rtab IN tablist
   LOOP
      EXECUTE IMMEDIATE 'DROP TABLE ' || rtab.table_name;

      UTL_FILE.put_line (
         log_file,
         'Dropped at ' || SYSTIMESTAMP || ' : ' || rtab.table_name);
   END LOOP;

   UTL_FILE.put_line (log_file, 'Completed Drop at ' || SYSTIMESTAMP);
   UTL_FILE.FCLOSE (log_file);
END XX_DROP_CR_BKUP_TABLES;
/

 

For this procedure to work, the schema owning this procedure should be granted these privileges explicitly.

grant select on dba_segments to SYSTEM;
grant drop any table to SYSTEM;

 

 

Active or Recently Used Printers in Oracle EBS

Recently had a request from one of the admins for list of printers used in the EBS application and how many jobs are directed to a printer. The following SQL provided what the admin needed, thought a good one to share…

select distinct fcr.printer, fu.user_name, 
       fu.description, count(*) jobs
from apps.fnd_concurrent_requests fcr, apps.fnd_user fu
where fcr.requested_by = fu.user_id
and (fcr.printer is not null and fcr.printer not in  ('noprint','LOCAL_PRINT','LOCAL','LOCAL_PRINTTO', 'LOCAL_PREVIEW'))
group by fcr.printer, fu.user_name, fu.description;

The caveat is that if you purge concurrent requests, the information is dependent on the records available in concurrent requests table…

Hope this helps someone, or if there is a better way to find the printer usage, please let me know… have a great day!