I am trying to insert queries from a sql file in shell script using sqlplus.
Now, some queries can fail because of incorrect schema.
So I want to commit all transactions only if all queries succeed.
The main problem is that, I would like to execute all queries irrespective of any error and rollback all queries if there was at least one error.
The idea behind executing all queries is to find the queries which would error out and create schema fix for the same.
I am using this command:
cat "temp.sql" | sqlplus -s sys/oracle@xe as sysdba
But this will auto-commit once the sqlplus exits.
I cannot use set exitcommit off
since I am using 11.1.
Is there any way to do this in shell script?
Best Answer
preliminary note
You issue the statement
You should avoid to pipe into sqlplus. Better you execute
sqlplus -s sys/oracle@xe as sysdba @temp.sql
An advantage is that no prompt will be generated in the output file. You can better control how the output looks like. Some input will produce results that make sense when working interactively but not make sense when executing a batch job. I can't see any advantage in piping commands to sqlplus.
This is not the behavior if you issue DML statements. This can make your data inconsistent.
So your script must contain the right statements so that all can be rolled back.
SET EXITCOMMAND was introduced in 11.2 to SQL*Plus. I don't think that it added something really new to SQL*Plus. You can use the WHENEVER commands to control the SQL*Plus behavior.
So I assume if the first error occurs you want to rollback and exit.
Therefore you should start your script with the WHENEVER SQLERROR statement
If an SQL error occurs the transaction will be rolled back and SQL*Plus will be exited. The error code that SQL*Plus is an OS-system depended value that signals an error
Maybe a WHENEVER OSERROR command should be executed, too
Of course AUTOCOMMIT should not be enabled, but
is the default, so you must not execute this command.
You can add these statements to the site profile or user profile scripts (glogin.sql or login.sql) so that they will be executed automatically whenever you connect to a database, if this makes sense.
Here draft how you can run your scrip.
sqlplus script run01.sql
shell script main1.sh
You added a new requirement:
You can again run the script an rollback end exit if the first error occurs. If that happens you can run your script again but now you don't exit in case of error but continue with the execution of the script. At the end of the script you roll back all transactions using the {EXIT COMMAND]8.
sqlplus script run02.sql
shell script main2.sh
This is my preferred solution. The only disadvantage I can see is that the statements of the temp.sql script that are executed until the first error occurs are executed two times: in script run01.sql and in script run02.sql. In a Linux environment you can try to avoid this by running the whole script and analyze the logfile with the
grep
statement an then exit the session with commit or rollback, depending on the result of this analysis.sqlplus script run03.sql
shell script main3.sh
shell script analyze_logfile.sh