sqlplus not properly ended script - oracle

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.

Related

SQLplus Error handling for nested scripts

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

Handling ORA error in Unix shell script

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;

Oracle Error Handling in Bash Script

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

Stop execution of PL/SQL when error without using raiserrror

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.

Running pl/sql in Korn Shell(AIX)

I have a file to execute in Ksh written by someone. It has a set of commands to execute in sqlplus.
It starts with,
sqlplus -s $UP <<- END
followed by a set of ddl commands such as create,drop,etc.,
When I execute the file in the shell, I get the error in the starting line quoted above.
I understand "-s" starts the sqlplus in silent mode and $UP is the connection string with username/password. But I couldn't make heads or tails of "<<- END" part(Many sites from google says input redirection is "<<" not "<<-"). So I presumed the error must be in that part and removed it from the file.
Now it reads,
sqlplus -s $UP
But once I execute the file, It waits for input from the shell, instead of reading the rest of the lines from the file. How would I make sqlplus to execute the ddl commands in the rest of the file?. Thanks in advance.
Here "END" is a block marker and "-" is not required.
For running sqls from a shell script , One simple example is given below.
sqlplus system/manager << ENDOFSQL
whenever sqlerror exit sql.sqlcode;
select sysdate from dual;
exit;
ENDOFSQL
Thanks,
Rinson KE
DBA

Resources