2020-08-06

Execute as sysdba

One can use os_command package to create and execute script from database server as sysdba user. Oracle white paper about this package
Steps to implement:

  1. Create directory to store file and grant permission to user
create or replace directory &tmpdir as '&tmppath';
grant read, write, execute on directory &tmpdir to &username;
  1. Grant execute permissions
begin
  dbms_java.grant_permission
      (upper('&username'),
       'java.io.FilePermission',
       '<<ALL FILES>>',
       'read,write,execute');
  dbms_java.grant_permission
      (upper('&username'),
       'java.lang.RuntimePermission',
       '*',
       'writeFileDescriptor');
end;
/
  1. Write file content with SQL or PL/SQL commands
--run sqlplus script
begin
  lob_writer_plsql.write_clob(
    '&tmpdir', '&scriptname',
q'[#!/bin/bash

ORACLE_SID=&dbname
ORACLE_HOME=/data/oracle/product/&dbver.&subver
PATH=/bin:/sbin:/usr/bin:${PATH}
export ORACLE_SID ORACLE_HOME

$ORACLE_HOME/bin/sqlplus -l -s / as sysdba <<!!!
--WRITE HERE WHAT TO DO

--example
SELECT * FROM sys.metaview\$;

--example (notice how to wrap handle "/" char)
BEGIN
  NULL;
END;
]'||q'[/

exit
!!!

exit 0
]'
  );
end;
/

&dbver and &subver can be extracted by query

column dbver new_value dbver
select regexp_substr(banner, 'Release (\d+.\d+.\d+.\d+).\d+', 1, 1, '', 1) dbver
from v$version
where banner like 'Oracle Database%';
  1. Execute script
declare
  c clob;
begin
  c := os_command.exec_CLOB('chmod 755 &tmppath/&scriptname');
  c := os_command.exec_CLOB('&tmppath/&scriptname');
  dbms_output.put_line(c);
  c := os_command.exec_CLOB('rm &tmppath/&scriptname');
end;
/

Комментариев нет: