oracle-databaseprocedurelog-files

Generating procedure logfile and inserting date time


Friends...

DB: Oracle11gR2

OS: Linux

I have created package with couple of procedure, procedure executes alter table move... , index rebuild command on database.

I'm doing below

  1. Run ksh shell script -> execute procedure
  2. Procedure runs alter table, rebuild index commands on database
  3. Procedure completes
  4. Shell script ends.

I can generate logfile for the shell script but whatever gets executed by procedure doesn't get recorded inside shell script logfile. I understood since db session created by procedure it won't record anything in shell logfile.

So how can I

  1. Record everything in logfile which is executed by both procedures in the same package?
  2. Also trying to put current datetime within procedure dmbs_out.put_line command?
  3. Is it possible to run both procedure after connecting database once instead of 2 time connecting database and executing procedure?

There might be table/table partition move syntax error but I'm only trying to trap when table move started and when finished with datetime so to identify total time taken.

*** ksh script
#!/bin/ksh
...
...
...
$LOG_FILE = move_tbs.log

echo -e "set serveroutput on\n exec move_tbs.moveTable;"|$ORACLE_HOME/bin/sqlplus/@db_alias | head -l

echo -e "set serveroutput on\n exec move_tbs.moveTablePart;"|$ORACLE_HOME/bin/sqlplus/@db_alias | head -l

DB Package / Procedure

*** Procedure
create or replace package move_all

procedure moveTable

dbms_output.put_line("CURRENT TIME" 'alter table '|| owner || '.' || table_name || 'move');

Execute immediate 'alter table '|| owner || '.' || table_name || 'move';
dbms_output.put_line("COMPLETED TIME" : CURRENT_TIME);

end moveTable;

-------------------------------------------
procedure moveTablePart

dbms_output.put_line("CURRENT TIME" 'alter table '|| owner || '.' || table_name || 'move');

Execute immediate 'alter table '|| owner || '.' || table_name || 'move partition';
dbms_output.put_line("COMPLETED TIME" : CURRENT_TIME);

end moveTablePart;
end move_all
/

Solution

  • You could just put both exec commands in your echo construct. But you can use a 'heredoc' to simplify running both together, and it's a easier to read and maintain too. Something like:

    LOG_TBS_MOVE=move_tbs.log
    
    (
    $ORACLE_HOME/bin/sqlplus -s -l user/passwd@db_alias <<!EOF
    set serveroutput on
    exec move_tbs.moveTable;
    exec move_tbs.moveTablePart;
    exit
    !EOF
    ) > $LOG_TBS_MOVE
    

    The herdoc start and end markers in this example !EOF - have to match exactly. They can be anything you like as long as there's no chance of anything inside the heredoc accidentally ending it. And the end marker has to be at the start of a line, it can't be indented.

    The parentheses around the SQL*Plus and heredoc can enclose multiole commands and all output from within them goes into the log. They aren't really necessary here as there is only one command inside but it's a fairly clear way of doing the redirection, I think.

    I'm only putting stdout into the $LOG_TBS_MOVE file; anything on stderr (which will not include any SQL errors) will still go to screen or to your main log if you redirect stderr for that.

    To show the time in your output, don't enclose the current_time part in quotes, use string concatenation, and use the right function:

    dbms_output.put_line(to_char(sysdate, 'HH24:MI:SS') ||
      'alter table '|| owner || '.' || table_name || 'move');
    
    dbms_output.put_line('COMPLETED TIME: ' || to_char(sysdate, 'HH24:MI:SS'));
    

    Or you could display the time from the shell instead, within the parentheses; that would also then go into the same log file.


    You haven't shown a username or password in your SQL*Plus calls; you probably just hid them, but if you are connecting as SYS via /, you really shouldn't be creating objects in that schema. Create a new schema and work in that.