How to conditionally exit SQL Plus from PL/SQL - plsql

I have a main SQL script (say main.sql) which includes other files like so:
-- Contents of main.sql
##init.sql
##body.sql
This template is fixed and I have no control over it. I can only put any code into the included files. Init.sql consists of PL/SQL code. Main.sql is run using SQL Plus. Now I want the following behavior of init.sql:
if cond1 is true then init.sql should terminate the execution of main.sql with an error such that body.sql doesn't run
if cond2 is true then init.sql should terminate the execution of main.sql with success such that body.sql doesn't run either
if cond3 is true then init.sql should successfully exit and the execution of body.sql should start
I am trying to get this behaviour using RAISE_APPLICATION_ERROR together with WHENEVER SQLERROR EXIT as I've learned that this is the only way of terminating an execution in SQL Plus completely, but I have troubles in achieving the bullet No.2 as
I can't make init.sql exit to the operating system with 0 code. I've tried to set a bind variable and use WHENEVER SQLERROR EXIT :retcode but :retcode appears to be empty when EXIT is called even if dbms_output.put_line outputs the correct value of this variable immediately before calling RAISE_APPLICATION_ERROR
This situation is normal and I'd rather not have an Oracle exception appearing
Could you help me to accomplish the bullet No.2 or maybe suggest a totally different approach overall.

You could handle different return codes by conditionally calling one or another sql file containing the return code you like:
cond1.sql:
WHENEVER SQLERROR EXIT 1
cond2.sql:
WHENEVER SQLERROR EXIT 0
Then here is how your init.sql starts:
--> Variable for init condition
col the_cond New_value the_cond noprint
--> select into condition variable
Select decode(smthg, 1, 'cond1', 2, 'cond2') the_cond
From table Where (whatever);
-- call to the host for the file:
#/path/to/the_file/&the_cond
begin
-- then here an exception will cause exit, with return code set right before in file the_cond
end;
/
Not very satisfying, but hopping it helps :)

This should work:
init.sql:
WHENEVER SQLERROR EXIT 0
BEGIN
IF COND2 THEN
RAISE_APPLICATION_ERROR(-20001, 'Cant continue');
END IF;
END;
/
WHENEVER SQLERROR EXIT 1
BEGIN
IF COND1 THEN
RAISE_APPLICATION_ERROR(-20001, 'Cant continue');
END IF;
END;
/

Related

validate_conversion does not compile in package but as standalone procedure

I'm getting an compilation error, when I try to use validate_conversion in plsql.
Error: PLS-00801: Interner Fehler [*** ASSERT at file pdz2.c, line 5361; The_Exp is null.; TEST__DBNAME__B__2920081[10, 3]]
Line: 10
Text: END;
Funny thing is, this error only occurs if compiled in a package. An MWE is:
CREATE OR REPLACE PACKAGE test IS
PROCEDURE my_VALIDATE_CONVERSION(asNbr VARCHAR2);
END test;
/
CREATE OR REPLACE PACKAGE BODY test IS
PROCEDURE my_VALIDATE_CONVERSION(asNbr VARCHAR2) IS
BEGIN
CASE VALIDATE_CONVERSION(asNbr AS NUMBER, '999999D99', ' NLS_NUMERIC_CHARACTERS = '',.''')
WHEN 1 THEN
DBMS_OUTPUT.PUT_LINE('He');
ELSE
DBMS_OUTPUT.PUT_LINE('Cu');
END CASE;
END;
BEGIN
NULL;
END test;
/
If compiled as standalone procedure my_VALIDATE_CONVERSION it works just fine.
CREATE OR REPLACE PROCEDURE my_VALIDATE_CONVERSION(asNbr VARCHAR2) IS
BEGIN
CASE VALIDATE_CONVERSION(asNbr AS NUMBER, '999999D99', ' NLS_NUMERIC_CHARACTERS = '',.''')
WHEN 1 THEN
DBMS_OUTPUT.PUT_LINE('He');
ELSE
DBMS_OUTPUT.PUT_LINE('Cu');
END CASE;
END;
What's going on here?
Im using:
PL/SQL Developer Version 13.0.6.1911 (64 bit)
Oracle Database 18c Standard Edition 2 Release 18.0.0.0.0
Seems like a bug in the database. I would try upgrading to Oracle 19c or apply the latest patch set to your database. I was able to compile your package in my database (version 19.6.0.0.0) without any errors.
This internal failure for sure will happen with the procedure compilation. The fact that it did not suggests that the compilation of the package was done with PLSQL_DEBUG turned on, and the compilation of the procedure was done without.
When you use this function in package in
Select Validate_Conversion(String AS Number) Into variable From Dual, is compiled successful.
Select Validate_Conversion(p_Oran AS Number) Into IsNumeric From dual; --COMPILED
IsNumeric := Validate_Conversion(p_Oran AS Number); --FAILURE
If Validate_conversion(p_Oran AS Number) = 0 Then --FAILURE
enter image description here

Pass parameter to .sql file from Batch file (MariaDB)

I have a situation where I want to pass 1 parameter while calling the sql file from .bat file. Based on that parameter I want to perform below action:
If (Passed parameter) = 1 then
use <abc>';
else
use <xyz>;
end if;
Explored the option where this can be done using -e parameter, but not able to do that successfully. Can someone help me in resolving this problem?
Pseudo code:
If (Schema Flag) = 1 then
use <abc>';
else
use <xyz>;
end if;

how to guess random values from user in pl sql

could someone help?
declare
ran int:=dbms_random.value(1,5);
num number;
begin
dbms_output.put_line('enter the num');
num:=&num;
if num<ran then
&dbms_output.put_line('Your num is less'||ran);
elsif num>ran then
&dbms_output.put_line('Your num is greater'||ran);
else
&dbms_output.put_line('Equal'||num||'='||ran);
end if;
while num=ran loop
&dbms_output.put_line('enter the num');
num:=&num;
end loop;
end;
there is some problems ?
what is wrong?
how to guess random numbers what's wrong
You would need to prompt for the number separately, and then use the value in a PL/SQL block once you have it.
Substitution variables are a SQL*Plus feature and not part of the core PL/SQL language (which is not interactive), so the following works in SQL*Plus. Client applications such as PL/SQL Developer emulate it to varying degrees, so it may also work in those (for example in PL/SQL Developer you would run it in a Command window, or in TOAD you'd use the 'Run as script' option). You may also be able to do something in Apex or using a third party scripting language such as Perl, Python, PowerShell etc.
accept mynumber number format 0 prompt "Enter a number between 1 and 5: "
declare
ran int := dbms_random.value(1, 5);
begin
if &mynumber < ran then
dbms_output.put_line('&mynumber is less than ' || ran);
elsif &mynumber > ran then
dbms_output.put_line('&mynumber is greater than ' || ran);
else
dbms_output.put_line('&mynumber = ' || ran);
end if;
end;
/
I'm not sure what the loop in your example is supposed to do. If you want it to prompt for input repeatedly in a loop you will need to write something in a separate scripting language or another development framework.

Pl-sql Procedure to print table details

SQL. I have created 1 procedure but I am not getting the desired output. My procedure is below:
--/
CREATE OR REPLACE procedure Update_TB_INTERACTLOG
IS
BEGIN
FOR records in (select TNAME from tab where TNAME like 'TB_INTERACTLOG%' and TABTYPE = 'TABLE')
LOOP
dbms_output.put_line(records.TNAME||' modified');
END LOOP;
END;
/
There are 7 records I am getting from select query.
This I am getting in Log Output.
13:10:02 [CREATE - 0 row(s), 0.031 secs] Command processed. No rows were affected
... 1 statement(s) executed, 0 row(s) affected, exec/fetch time: 0.031/0.000 sec [0 successful, 1 warnings, 0 errors]
It looks as if you have created the procedure but not executed it. To execute it, run the following code:
exec Update_TB_INTERACTLOG;
Furthermore, you will need to turn on DBMS output in the tool you're using to run it (unless it's SQL*plus).
And please not that the procedure wasn't properly compiled (1 warnings). The procedure should probably end with:
END Update_TB_INTERACTLOG;
instead of:
END;

Accessing Bind Variable in PL/SQL

I am trying to run a program in the Oracle express edition editor. When I execute the program, I get an error
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
Can anyone help me understand why I am getting an error and how to fix the code?
VARIABLE gvn_total_salary NUMBER;
DECLARE
vn_base_salary NUMBER := 3000;
vn_bonus NUMBER := 1000;
BEGIN
:gvn_total_salary := vn_base_salary + vn_bonus;
END;
The output I'm getting
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
Run By SYSTEM
Parsing Schema SYSTEM
Script Started Thursday, April 26, 2012
3 seconds ago
Elapsed time 0.01 seconds
Statements Processed 1
Successful 0
With Errors 1
With the declaration of the bind variable, that code works fine for me in SQL*Plus
SQL> VARIABLE gvn_total_salary NUMBER;
SQL> DECLARE
2 vn_base_salary NUMBER := 3000;
3 vn_bonus NUMBER := 1000;
4 BEGIN
5 :gvn_total_salary := vn_base_salary + vn_bonus;
6 END;
7 /
PL/SQL procedure successfully completed.
SQL> print gvn_total_salary
GVN_TOTAL_SALARY
----------------
4000
Can you connect to the database using SQL*Plus and run the same thing?
What are you actually trying to accomplish? This script won't execute in sqlplus or Oracle Developer or any PL/SQL execution environment I can think of. In fact, I don't understand how you are passing the bind variable :gvn_total_salary and how you can get the error you are describing. You should get something like "bind variable gvn_total_salary" not declared.

Resources