0

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
/
homer
  • 423
  • 2
  • 11
  • 24

1 Answers1

1

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.

Alex Poole
  • 183,384
  • 11
  • 179
  • 318
  • I'm using tns alias to connect to db. I will test your recommendation and provide result here. This was such a nice and clean way to exec procedure surely will use with my daily programming. – homer Aug 21 '14 at 23:40
  • creating logfile failing with error "Syntax error at line 62: '<< unmatched – homer Aug 22 '14 at 16:53
  • @homer - then you have the start and end of the heredoc unmatched; do they both have `!EOF`? They need to be exactly the same. (The pling is optional and just habit; whatever value you use though, it has to be consistent). Just verified this works, though I've the log file assignment I'd copied form the question. – Alex Poole Aug 22 '14 at 16:58
  • creating logfile failing with error "Syntax error at line 62: '<< unmatched" ... In ksh script I'm already logging everything in $LOG_FILE and in between run I'm executing procedure and trying to write procedure log to another log (e.g. $LOG_TBS_MOVE). I think this error is due to that .. is that true? How to create another seperate log $LOG_TBS_MOVE? – homer Aug 22 '14 at 16:59
  • @homer - no, `<< unmatched` means you have a mismatch between whatever you have in the two places where I have `!EOF`. It's not to do with the logging. Changed the logging in the answer, and added a note about the heredoc markers. – Alex Poole Aug 22 '14 at 17:03
  • Whenever it connects and logs everything in the logfile it also logs all the sentences from the db login e.g. "conncted to oracle database 11g Enterprise Edition Release 11.2.0.3 ..... sql> sql> sql> ...." is there a way in our current syntax to avoid all this and just have the procedure output? – homer Aug 22 '14 at 19:01
  • @homer - I already added the `-s` flag on the last edit to suppress those. – Alex Poole Aug 22 '14 at 22:58
  • thanks for -l -s, I have marked your answer as correct. I wish I could give more bounty points for detailed explanations. – homer Aug 25 '14 at 22:33