Define Procedures inside Packages - plsql

I have created some Procedures in SQL Developer, and they are working fine. However I am now creating a Package to include all those Procedures, and can't seem to figure out the right way to code the Package as it returns the following error (refering to the PACKAGE BODY's CREATE):
PLS-00103: Encountered the symbol "CREATE"
Here is my code:
CREATE OR REPLACE PACKAGE package_test AS
PROCEDURE copy_object;
END package_test;
CREATE OR REPLACE PACKAGE BODY package_test AS
PROCEDURE copy_object IS
CURSOR object_cursor IS
SELECT COD_OBJECT, OBJECT_NAME FROM OBJECT;
object_rec object_cursor%rowtype;
BEGIN
EXECUTE IMMEDIATE 'TRUNCATE TABLE DATABASE2.D_OBJECT';
FOR object_rec IN object_cursor
LOOP
INSERT INTO DATABASE2.D_OBJECT (COD_OBJECT,OBJECT_NAME) VALUES (object_rec.OOD_OBJECT,object_rec.OBJECT_NAME);
END LOOP;
COMMIT;
END copy_object;
END package_test;
I have done some searching and the only thing I can think of is maybe some problem related to the definition on the CURSOR...not sure though. Thanks in advance

I successfully ran this in sqlplus and sqldeveloper (F5 in sqldeveloper: "Run Script"). I changed the two dml statements since my schema is different.
SQL> CREATE OR REPLACE PACKAGE package_test AS
2
3 PROCEDURE copy_object;
4
5 END package_test;
6 /
Package created.
SQL>
SQL> CREATE OR REPLACE PACKAGE BODY package_test AS
2
3 PROCEDURE copy_object IS
4 CURSOR object_cursor IS
5 SELECT * from dual;
6
7 object_rec object_cursor%rowtype;
8
9 BEGIN
10 EXECUTE IMMEDIATE 'TRUNCATE TABLE DATABASE2.D_OBJECT';
11 FOR object_rec IN object_cursor
12 LOOP
13 NULL; --INSER INTO DATABASE2.D_OBJECT (COD_OBJECT,OBJECT_NAME) VALUES (object_rec.OOD_OBJECT,object_rec.OBJECT_
NAME);
14 END LOOP;
15 COMMIT;
16 END copy_object;
17 END package_test;
18 /
Package body created.
SQL>

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

How to conditionally exit SQL Plus from PL/SQL

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;
/

Im getting an Warning: Procedure created with compilation errors

I'm beginner of pl/sql and I'm learning.
This is my table.
select * from s;
SLNO ENAME SAL
------ -------------------- ----------
1 Shiv 8000
2 Pankaj 9000
3 Prasath 10000
This is my procedure:
set serveroutput on
create or replace procedure p1(n number)
is wname varchar(20);
begin
select ename into wname from s where eid=n;
dbms_output.put_line('------');
dbms_output.put_line('employee name:='||wname);
dbms_output.put_line('------');
end;
I'm getting a warning:
Procedure created with compilation errors.
If I execute the above query. Can anyone please suggest where I'm going wrong please..
You can use the following command.
show errors procedure procedure_name;
to get the list of errors and check that.
There is no column named EID on your table S.
put parameter type IN.
Give procedure like create or replace procedure p1(n IN s.eid%TYPE)
It will work.
I think there's a typo in your program,
try
SET SETVEROUTPUT ON
all in capitals.

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