0

I'm running several sql scripts from bash. I want to see the summery of ORA-errors before adding commit. Something like this:

#!/bin/bash
S_DB2_CONNECTOR=""
echo "My statement"
SQL_STM=$( echo "UPDATE ..." | sqlplus login/pass@bd );
echo "Output:"
echo "$SQL_STM"
echo "searching for errors...."
echo $LOG_VAR | grep "ORA"
echo "before commit"
wait 1000
echo "COMMIT;" | sqlplus -s login/pass@bd;

But this doesn't work, because sqlplus session is broken and !SURPRISE! sqlplus added auto commit after SQL_STM execution.

How to parse sqlplus output for ORA-/ST-errors before commit? Preferable in this terminal screen.

Maybe I do not need bash for parsing and sqlplus can do it for me? (So the session state will be preserved).

1

1 Answer 1

1

if you want to rollback / do some extra stuff in the case of an ORA code, then do it all in the SQL*PLUS session.

i.e. run it as a script.

set serverout on
begin
  update...;

exception
  when others -- others is a catch all, you can catch specific codes too
  then 
    rollback;
    dbms_output.put_line('Error!');
    dbms_output.put_line(sqlerrm); -- prints full error string
end;
/

if you just want to signal to bash that a sql statement failed , you can just set as the first thing in sql*plus. whenever sqlerror exit sql.sqlcode (or whenever sqlerror (exit -1 etc) instead (see here). This would stop on the first error and return to your schell script with an appropriate return code.

you can nest blocks eg:

begin
  update ..;
  begin
    select id into v_id
      from tab
     where ...;
  exception
    when no_data_found
    then
      null;-- ignore that we didnt find a row
  end;
  -- if the select fails, we continue from here..
  delete...;
  begin
    savepoint mysave;
    your_proc(...);
  exception
   when others
   then
     rollback to mysave; -- of the call to your_proc fails, lets just toll that back alone
  end;

end;

etc.

if you needed it to be interactive, you could do something like (dbms_alert)[http://docs.oracle.com/cd/B19306_01/appdev.102/b14258/d_alert.htm#CHDCFHCI]:

sqlplus /<<EOF | tee -a my.log
set feedback on verify on serverout on 
-- IE YOUR CODE HERE..
select * from dual;
begin
  null;
end;
/
-- END OF YOUR CODE..
-- now lets wait for an alert from another session:
declare
  v_message  varchar2(32767);
  v_status   number;
begin
  DBMS_ALERT.REGISTER('should_i_commit');
  DBMS_ALERT.WAITONE('should_i_commit', v_message, v_status); -- there is a timeout parameter you can set too
  if (v_message = 'Y')
  then
    dbms_output.put_line('I committed');
    commit;
  else
    dbms_output.put_line('I rolled back');
    rollback;
  end if;
end;
/
EOF

then in another session you can issue:

SQL> exec dbms_alert.signal('should_i_commit', 'N');

PL/SQL procedure successfully completed.

SQL> commit;

Commit complete.
Sign up to request clarification or add additional context in comments.

8 Comments

I want to make decision by myself. Not automatic on errors. Some ORA- errors are OK, some are not. Thanks for the advice. I found this docs.oracle.com/cd/E11882_01/server.112/e16604/ch_twelve052.htm
Unfortunatly my sql knowledge is worse, than bash. Could you please explain, what exactly would this code do? dbms_output.put_line(sqlerrm); Will it execute the sql code (just normal + output all ORA-errors just before SQL commit request?
@idobr if a statement failed, it will fall straight into the when others block, and run whatever is in there (ie it wouldn't process any more of the code in the begin part).
Thanks for your attention. So it will break script execution even because of negligible erros, won't it? I got the point that I can specify, what errors codes are important. Can I just write all errors to some place (without break) and than output it before commit decision?
@idobr yes you can "ignore" trivial errors easily by nesting a begin/end block trapping that error. Eg begin update... ; begin select id into void from tab; exception when no_data_found then null; end; delete... ;... End;. In that case of your select failed with no rows found, execution would continue to the delete (as only the inner begin end block failed. (I'm travelling so can't update my answer properly at the moment but I can add a more complex example of that soon if you like)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.