I'll try to explain the best I can.
I want to run a script through sqlplus. I know that I can use # or ## or START.
I also know that to stop and exit in case of errors, I can use
WHENEVER SQLERROR EXIT SQL.SQLCODE ROLLBACK
What I need and I don't know is: is it possible to break the execution of a nested script in case of error, but continue in the main script? CONTINUE in the WHENEVER is not what I want. The nested script must stop processing in case of error.
It's for CI/CD automation script I'm writing.
like this:
SET ECHO OFF
WHENEVER SQLERROR EXIT SQL.SQLCODE ROLLBACK
START SCRIPT_WITH_ERRO.sql
PROMPT "This line should be prompted even if there was an error before"
SHOW ERRORS
Related
i have a plsql script, which is not properly terminated:
create or replace package mypackage
... (no semicolon/forward slash at the end)
the script is executed with sqlplus (12.1) on windows powershell:
sqlplus user/pass#host #my_not_properly_ended_file.pks
i would expect sqlplus to terminate with exit code 1 and an error message, but instead it prompts for input.
how can i get an error message and exit code in this situation?
edit: solution should also work with dml statements that are not terminated with a semicolon.
You can use shell redirection instead of #:
sqlplus user/pass#host < my_not_properly_ended_file.pks
This will also prevent it getting 'stuck' if the script doesn't end with an exit command.
However, it won't return an error code to the shell in either case. As far as SQL*Plus is concerned you put the incomplete statement into its buffer but never attempted to execute it (as there was no slash); and as it didn't run, it didn't error. So setting whenever sqlerror or whatever won't make any difference either.
I have a job in Jenkins that uses two commands in a Execute Shell Command.
The first does a test job, the second creates a report out of this. It looks a littlebit like this:
node_modules/gulp/bin/gulp.js run-cucumber-tests
node_modules/gulp/bin/gulp.js create-cucumber-report
If there are test failures, the command will exit with code 1. This means the second command won't even be fired. But even though the first command failed, I want the report to be created!
What I've tried is to do this:
node_modules/gulp/bin/gulp.js run-cucumber-tests || true
node_modules/gulp/bin/gulp.js create-cucumber-report
Now the report does get created but the build is marked as succeeded. That's not what I want. I want the jenkins build job to eventually fail, but with the reports created.
I was wondering, maybe I can catch the outcome of the first command in a variable, continue with the second and then throw it after the second command.
You can use set +e to let the script continue even if an error occurred and then use $? to capture the result of the last command. With exit you can force the result code of the script to the previously captured value.
set +e
node_modules/gulp/bin/gulp.js run-cucumber-tests
RESULT=$?
node_modules/gulp/bin/gulp.js create-cucumber-report
exit $RESULT
I am trying to execute a script which actually runs a SQL and returns the value , write to to a CSV file and send it.
/data/oracle/product/10.2.0.4/bin/sqlplus -s user_name/password#DBName #/export/home/script/abc.sql
I want to capture the error whenever there is any error while running the SQL part but it always hangs.
I tried putting "(($?)) && ((ERRORS += 1))" after above statement but it never reaches to that line.
I want to capture the error code in a variable ERROR and exit with the error code.
Kindly help
you can put it under TRY-Catch block. refer this manual
To be able to capture the error via shell script you have to remove you error handling from your SQL and set the script to rollback and return the error:
WHENEVER OSERROR EXIT 9 ROLLBACK;
WHENEVER SQLERROR EXIT SQL.SQLCODE ROLLBACK;
How can I error handling in SQLPlus , printing out customised messages when an error is encountered. I have put my code below.
My Code
#!/bin/bash
echo "My Scripts run below"
sqlplus -S UID1/UID2#DB1<< EOF
whenever sqlerror exit sql.sqlcode;
#/path/Script1
#/path/Script2
exit;
EOF
echo "My Scripts have run"
Output
My Scripts run below
SP2-0310: unable to open file "/path/Script1.sql"
SP2-0310: unable to open file "/path/Script2.sql"
My Scripts have run
Required Output
My Scripts run below
**Below error in Script1**
SP2-0310: unable to open file "/path/Script1.sql"
**Below error in Script2**
SP2-0310: unable to open file "/path/Script2.sql"
My Scripts have run
Indeed, SQLPlus return code is always 0 fr om my experience, so I advise you to do what I had to do in previous projects: redirect scripts output in a file, then parse it to find SPx-xxxx or ORA-xxxx expressions that indicate errors.
WHENEVER SQLERROR detects an error in a SQL command or PL/SQL block. You should use WHENEVER OSERROR instead to catch operating system errors.
WHENEVER OSERROR EXIT FAILURE
If in doubt which error code is returned, you could think about hardcoding a number:
WHENEVER OSERROR EXIT 1
For clarity, I'd change the last EXIT to
EXIT SUCCESS
You won't be able to catch both errors for script1 and script2. After the first error, your SQL*Plus scripts exits and hands back control to bash.
About what to do with the exit code back in bash, see Error handling in Bash
See this code:
test.sh
#!/bin/bash
echo "hello!"
klsdslkdsd
echo "bye"
When I run it I get:
hello!
/tmp/test.sh: line 3: klsdslkdsd command not found
bye
Although there is a syntactic error, the execution goes one (is a script after all).
Now, if I do:
testWithStop.sh
#!/bin/bash
set -e
echo "hello!"
klsdslkdsd
echo "bye"
I get:
hello!
/tmp/test.sh: line 5: klsdslkdsd command not found
The execution stops because I get an exit error from every executed line. If exit != 0 it aborts.
I would like to replicate this behavior in a set of (oracle) PL/SQL (and solely SQL) code.
At this point, even with error, the Oracles DB Manager manages the error gracefully and don't stop the execution of the SQLs. I would like that, when an error (syntactic or semantic) is found, the program aborts but without touching the logic of the program (if so, I would have to change several hundreds of PL/SQL and is not possible).
I know I could do it using raiserror or creating a macro anonymous block that encapsulate portions of my codes, so I could retrieve the exceptions. As I said, it could not be possible to do with several hundreds (could be thousands) of isolated (and logic complex) PL/SQLs
Is there an equivalent to set -e in SQL or an elegant way to do it?
EDIT:
In particular, I´m executing (and calling) de PL/SQLs via a shell script (bash).
For example, the sqlbash.sh file:
#!/bin/bash
sqlplus ..... <<EOF
select * from table;
sdsdsfdsf <--- intentional error!
select * from table2;
EOF
If I called the script, I will get the syntactic error, but the execution goes on and doesn't abort. I would like to abort, for example, mimicking the behavior of an exit 1.
Something like:
#!/bin/bash
sqlplus ..... <<EOF
select * from table;
sdsdsfdsf <--- intentional error!
exit 1 <--- it will abort and the script WILL FAIL at this point
select * from table2;
EOF
I'm working with an scheduler, so, it is necessary for me to see that the script fails, not that it was executed and gave me warnings.
Your looking for WHENEVER SQLERROR and/or WHENEVER OSERROR SQL*Pus commands. They allow you to, among other things, exit if something bad happens in the middle of the script.
Put something like
whenever oserror exit 1
whenever sqlerror exit 2
at the top of your scripts, and you'll be able to tell from your shell script that something failed.