Getting error while compiling this PL/SQL block - oracle

Package
CREATE OR REPLACE PACKAGE EMP_DESIGNATION
AS
PROCEDURE EMP_DETAILS
(
design IN employee.designation%TYPE,
incentive IN number
);
END EMP_DESIGNATION;
CREATE OR REPLACE PACKAGE BODY EMP_DESIGNATION
AS
PROCEDURE EMP_DETAILS
(
design IN employee.designation%TYPE,
incentive IN number
)
AS
BEGIN
update Employee
SET SALARY = SALARY + incentive
where DESIGNATION = design;
dbms_output.put_line(SQL%rowcount || ' employee record(s) are updated');
END EMP_DETAILS;
END EMP_DESIGNATION;
/
Actually both this code is in same file I am getting bellow error message.
ERROR at line 2:
ORA-06550: line 2, column 4:
PLS-00905: object P11169.EMP_DESIGNATION is invalid
ORA-06550: line 2, column 4:
PL/SQL: Statement ignored
Can some one please help me out in figuring out the error.

If you use SQL*Plus, run
show err
or - elsewhere - query user_errors; both will tell you what's invalid.
When I tried it (with a dummy employee table), everything seems to be fine:
SQL> create table employee(designation number, salary number);
Table created.
SQL> CREATE OR REPLACE PACKAGE EMP_DESIGNATION
2 AS
3 PROCEDURE EMP_DETAILS
4 (
5 design IN employee.designation%TYPE,
6 incentive IN number
7 );
8
9 END EMP_DESIGNATION;
10 /
Package created.
SQL> CREATE OR REPLACE PACKAGE BODY EMP_DESIGNATION
2 AS
3 PROCEDURE EMP_DETAILS
4 (
5 design IN employee.designation%TYPE,
6 incentive IN number
7 )
8 AS
9 BEGIN
10 update Employee
11 SET SALARY = SALARY + incentive
12 where DESIGNATION = design;
13 dbms_output.put_line(SQL%rowcount || ' employee record(s) are updated');
14
15 END EMP_DETAILS;
16 END EMP_DESIGNATION;
17 /
Package body created.
SQL>

Related

How can i correct this error(The package is configured with translation errors)?

This is the question
-Create customers table and add these columns:
Id
Name
AGE
ADDRESS
SALARY
-Add 10 rows.
-Create a package with three procedures:
one that add a customer to the table.
one that removes a customer from the table.
one that lists all the customers.
-Create customers table and add these columns:
Id
Name
AGE
ADDRESS
SALARY
-Add 10 rows.
-Create a package with three procedures:
one that add a customer to the table.
one that removes a customer from the table.
one that lists all the customers.
CREATE TABLE customer(
customer_id NUMBER NOT NULL,
customer_name VARCHAR2(50) NOT NULL,
customer_age NUMBER NOT NULL,
customer_address VARCHAR2(50) NOT NULL,
customer_salary NUMBER NOT NULL,
PRIMARY KEY(customer_id)
);
INSERT INTO customer
VALUES
(1,'Ahemed',22,'wq1',2500);
INSERT INTO customer
VALUES
(2,'salem',24,'wq2',2000);
INSERT INTO customer
VALUES
(3,'Aboud',26,'wq3',2200);
INSERT INTO customer
VALUES
(4,'Tarek',27,'wq4',2100);
INSERT INTO customer
VALUES
(5,'Hazem',33,'wq5',3000);
INSERT INTO customer
VALUES
(6,'Hayder',32,'wq6',2300);
INSERT INTO customer
VALUES
(7, 'Sammy',35,'wq7',2700);
INSERT INTO customer
VALUES
(8,'Mohammed',20,'wq8',4000);
INSERT INTO customer
VALUES
(9,'Tayseer',18,'wq9',3600);
INSERT INTO customer
VALUES
(10,'Hamoud',40,'wq10',3100);
CREATE OR REPLACE PACKAGE mypackage AS
PROCEDURE add_customer(c_id customer.customer_id%type,
c_name customer.customer_name%type,
c_age customer.customer_age%type,
c_address customer.customer_address%type,
c_salary customer.customer_salary%type);
PROCEDURE remove_customer(c_id customer.customer_id%type);
PROCEDURE list_customer;
END mypackage ;
CREATE OR REPLACE PACKAGE BODY mypackage AS
PROCEDURE add_customer(c_id customer.customer_id%type,
c_name customer.customer_name%type,
c_age customer.customer_age%type,
c_address customers.address%type,
c_salary customer.customer_salary%type)
IS
BEGIN
INSERT INTO customer (customer_id ,customer_name,customer_age ,customer_address ,customer_salary)
VALUES(c_id, c_name, c_age, c_address, c_salary);
END add_customer;
PROCEDURE remove_customer(c_id customer.customer_id%type) IS
BEGIN
DELETE FROM customer
WHERE customer_id= c_id;
END remove_customer;
PROCEDURE list_customer(customer_id ,customer_name,customer_age ,customer_address ,customer_salar) IS
BEGIN
select * from customer;
END list_customer;
If i create this package the error is(The package is configured with translation errors) how can i solve it?
Table and package specification are OK (kind of):
SQL> CREATE TABLE customer(
2 customer_id NUMBER NOT NULL,
3 customer_name VARCHAR2(50) NOT NULL,
4 customer_age NUMBER NOT NULL,
5 customer_address VARCHAR2(50) NOT NULL,
6 customer_salary NUMBER NOT NULL,
7 PRIMARY KEY(customer_id)
8 );
Table created.
SQL> CREATE OR REPLACE PACKAGE mypackage AS
2 PROCEDURE add_customer(c_id customer.customer_id%type,
3 c_name customer.customer_name%type,
4 c_age customer.customer_age%type,
5 c_address customer.customer_address%type,
6 c_salary customer.customer_salary%type);
7
8 PROCEDURE remove_customer(c_id customer.customer_id%type);
9 PROCEDURE list_customer;
10 END mypackage ;
11 /
Package created.
But then, for some reason, you didn't follow the same recipe for package body:
SQL> CREATE OR REPLACE PACKAGE BODY mypackage AS
2 PROCEDURE add_customer(c_id customer.customer_id%type,
3 c_name customer.customer_name%type,
4 c_age customer.customer_age%type,
5 c_address customers.address%type,
6 c_salary customer.customer_salary%type)
7 IS
8 BEGIN
9 INSERT INTO customer (customer_id ,customer_name,customer_age ,customer_address ,customer_salary)
10 VALUES(c_id, c_name, c_age, c_address, c_salary);
11 END add_customer;
12
13 PROCEDURE remove_customer(c_id customer.customer_id%type) IS
14 BEGIN
15 DELETE FROM customer
16 WHERE customer_id= c_id;
17 END remove_customer;
18
19 PROCEDURE list_customer(customer_id ,customer_name,customer_age ,customer_address ,customer_salar) IS
20 BEGIN
21 select * from customer;
22 END list_customer;
23 end mypackage;
24 /
Warning: Package Body created with compilation errors.
What's wrong?
SQL> show err
Errors for PACKAGE BODY MYPACKAGE:
LINE/COL ERROR
-------- -----------------------------------------------------------------
19/41 PLS-00103: Encountered the symbol "," when expecting one of the
following:
in out <an identifier> <a double-quoted delimited-identifier>
table ... columns long double ref char standard time
timestamp interval date binary national character nchar
20/4 PLS-00103: Encountered the symbol "BEGIN" when expecting one of
the following:
not null of nan infinite dangling a empty json
SQL>
Line #19 is wrong:
19 PROCEDURE list_customer(customer_id ,customer_name,customer_age ,customer_address ,customer_salar) IS
So: if - apparently - you do know how to use parameters while declaring procedures, why didn't you do the same for list_customer? Besides, it wouldn't work anyway - in PL/SQL, a SELECT must have an INTO (and your procedure doesn't). I guess that at customer_id should be passed as a parameter (so I'm doing that in my example).
Moreover, all procedures you declare in package specification must exist in package body, with exactly the same description (you've used customer.address%type but that column doesn't exist in the table).
So, when fixed: specification:
SQL> CREATE OR REPLACE PACKAGE mypackage AS
2 PROCEDURE add_customer(c_id customer.customer_id%type,
3 c_name customer.customer_name%type,
4 c_age customer.customer_age%type,
5 c_address customer.customer_address%type,
6 c_salary customer.customer_salary%type);
7
8 PROCEDURE remove_customer(c_id customer.customer_id%type);
9 PROCEDURE list_customer (p_customer_id customer.customer_id%type);
10 END mypackage ;
11 /
Package created.
Body:
SQL> CREATE OR REPLACE PACKAGE BODY mypackage AS
2 PROCEDURE add_customer(c_id customer.customer_id%type,
3 c_name customer.customer_name%type,
4 c_age customer.customer_age%type,
5 c_address customer.customer_address%type,
6 c_salary customer.customer_salary%type)
7 IS
8 BEGIN
9 INSERT INTO customer (customer_id ,customer_name,customer_age ,customer_address ,customer_salary)
10 VALUES(c_id, c_name, c_age, c_address, c_salary);
11 END add_customer;
12
13 PROCEDURE remove_customer(c_id customer.customer_id%type) IS
14 BEGIN
15 DELETE FROM customer
16 WHERE customer_id= c_id;
17 END remove_customer;
18
19 PROCEDURE list_customer(p_customer_id in customer.customer_id%type)
20 --,customer_name,customer_age ,customer_address ,customer_salar) IS
21 is
22 l_row customer%rowtype;
23 BEGIN
24 select * into l_row from customer where customer_id = p_customer_id;
25 END list_customer;
26 end mypackage;
27 /
Package body created.
SQL>
This, at least, compiles. Does it do what you wanted it, I didn't try - I'll leave it to you.

How to use procedure within package in PL/SQL

How to create a Package with Procedure in it? Procedure will take designation and incentive as input and update the employee salary by adding the incentive for the given designation. Display the number of employee records that have got updated, e.g. ‘3 employee record(s) are updated’.
I have a table EMPLOYEE, with EMP_ID, EMP_NAME, SALARY and DESIGNATION.
The given Functional Requirements are:
Package name as EMP_DESIGNATION, and
Procedure signature:
EMP_DETAILS(design employee.designation%TYPE, incentive number);
The code which I tried is -
set serveroutput on;
CREATE OR REPLACE PACKAGE EMP_DESIGNATION AS
PROCEDURE EMP_DETAILS(
design employee.designation%TYPE,
incentive NUMBER) IS
BEGIN
UPDATE employee SET employee.salary = employee.salary + incentive
WHERE employee.designation = design;
dbms_output.put_line(SQL%ROWCOUNT || ' employee record(s) are updated');
END EMP_DESIGNATION;
END;
/
The output is-
Warning: Package Body created with compilation errors.
BEGIN
*
ERROR at line 1:
ORA-04063: package body "P10017.EMP_DESIGNATION" has errors
ORA-06508: PL/SQL: could not find program unit being called:
"P10017.EMP_DESIGNATION"
ORA-06512: at line 2
How to solve this error? Please help. Thank you in advance.
PL/SQL: Statement ignored
You have to create a package specification first, then its body. Something like this:
SQL> CREATE OR REPLACE PACKAGE emp_designation
2 AS
3 PROCEDURE emp_details (design employee.designation%TYPE, incentive NUMBER);
4 END emp_designation;
5 /
Package created.
SQL>
SQL> CREATE OR REPLACE PACKAGE BODY emp_designation
2 AS
3 PROCEDURE emp_details (design employee.designation%TYPE, incentive NUMBER)
4 IS
5 BEGIN
6 UPDATE employee
7 SET employee.salary = employee.salary + incentive
8 WHERE employee.designation = design;
9
10 DBMS_OUTPUT.put_line (
11 SQL%ROWCOUNT || ' employee record(s) are updated');
12 END emp_details;
13 END emp_designation;
14 /
Package body created.
SQL>

ora-06575 package or function is in an invalid state pl sql

I am new to pl sql and i am trying to call a procedure but i am getting the error ora-06575 package or function is in an invalid state.
What do you think i am doing wrong? Thanks
select * from NB_tfr_USERS; --previous table created
create or replace procedure nb_tfr_add_user
(
i_user_name in nb_tfr_users.name%type,
i_address in nb_tfr_users.address%type,
i_birthdate in nb_tfr_users.birthdate%type,
o_userid out nb_tfr_users.id%type,
o_errm out varchar2
) AS
--Variables
l_user_id number;
--Parameters invalid exception
error_params exception;
BEGIN
--validate parameters
--- name can not be empty
--- birthdate can be empty
if i_user_name is null or length(i_user_name) = 0 then
raise error_params;
end if;
--initialize variables
l_user_id := nb_seq_tfr_user_id.nextval;
--insert new user
insert into NB_tfr_USERS (id, name, address, birthdate)
values (l_user_id, i_user_name, i_address, i_birthdate);
--deal with exceptions
exception
when error_params then
o_errm := 'Invalid Parameters!';
dbms_output.put_line(o_errm);
when others then
dbms_output.put_line('Error: '||sqlerrm);
o_errm:=substr(1,150,sqlerrm);
raise;
END NB_tfr_ADD_USER;
call
nb_tfr_add_user(54,'tf','lx',12121989);
So when i try to call the procedure i get the error.
Well, it looks OK - apart from the fact that you incorrectly called the procedure.
Here's a test case.
SQL> create table nb_tfr_users
2 (id number, name varchar2(10), address varchar2(10), birthdate date);
Table created.
SQL> create sequence nb_seq_tfr_user_id;
Sequence created.
The procedure:
SQL> create or replace procedure nb_tfr_add_user
2 (
3 i_user_name in nb_tfr_users.name%type,
4 i_address in nb_tfr_users.address%type,
5 i_birthdate in nb_tfr_users.birthdate%type,
6 o_userid out nb_tfr_users.id%type,
7 o_errm out varchar2
8 ) AS
9 --Variables
10 l_user_id number;
11 --Parameters invalid exception
12 error_params exception;
13 BEGIN
14 --validate parameters
15 --- name can not be empty
16 --- birthdate can be empty
17 if i_user_name is null or length(i_user_name) = 0 then
18 raise error_params;
19 end if;
20
21 --initialize variables
22 l_user_id := nb_seq_tfr_user_id.nextval;
23
24 --insert new user
25 insert into NB_tfr_USERS (id, name, address, birthdate)
26 values (l_user_id, i_user_name, i_address, i_birthdate);
27
28 --deal with exceptions
29 exception
30 when error_params then
31 o_errm := 'Invalid Parameters!';
32 dbms_output.put_line(o_errm);
33
34 when others then
35 dbms_output.put_line('Error: '||sqlerrm);
36 o_errm:=substr(1,150,sqlerrm);
37 raise;
38 END NB_tfr_ADD_USER;
39 /
Procedure created.
SQL>
Testing - it shows how you should have called it. As there are 3 IN and 2 OUT parameters, that's what you should have done as well.
SQL> set serveroutput on
SQL> declare
2 l_userid nb_tfr_users.id%type;
3 l_Errm varchar2(200);
4 begin
5 nb_tfr_add_user(i_user_name => 'tf',
6 i_address => 'lx',
7 i_birthdate => sysdate,
8 o_userid => l_userid,
9 o_errm => l_errm);
10 dbms_output.put_Line(l_userid ||' '||l_errm);
11 end;
12 /
PL/SQL procedure successfully completed.
SQL> select * from nb_tfr_users;
ID NAME ADDRESS BIRTHDAT
---------- ---------- ---------- --------
1 tf lx 09.09.19
SQL>
If you got the error, it - obviously - means that there's something wrong. I don't know what, but - maybe you forgot to create the sequence.
Anyway: after creating stored procedures, check whether everything is OK by running (in SQL*Plus) show err, e.g.
SQL> create or replace procedure p_test is
2 begin
3 insert into abc (id) values (seq_does_not_exist.nextval);
4 end;
5 /
Warning: Procedure created with compilation errors.
SQL> show err
Errors for PROCEDURE P_TEST:
LINE/COL ERROR
-------- -----------------------------------------------------------------
3/3 PL/SQL: SQL Statement ignored
3/15 PL/SQL: ORA-00942: table or view does not exist
SQL>
Or, query user_source:
SQL> select line, text, attribute from user_errors where name = 'P_TEST';
LINE TEXT ATTRIBUTE
----- -------------------------------------------------- ---------
3 PL/SQL: ORA-00942: table or view does not exist ERROR
3 PL/SQL: SQL Statement ignored ERROR
SQL>
I suggest you do the same and see what's wrong with the procedure.

ORA-00932: inconsistent datatypes: expected - got -

I have been using Oracle(10g.2) as a PHP programmer for almost 3 years, but when I gave an assignment, I have tried to use the ref cursors and collection types for the first time. And I
've searched the web, when I faced with problems, and this ora-00932 error really overwhelmed me. I need help from an old hand.
Here is what I've been tackling with,
I want to select rows from a table and put them in a ref cursor, and then with using record type, gather them within an associative array. And again from this associative array, make a ref cursor. Don't ask me why, I am writing such a complicated code, because I need it for more complex assignment. I might be sound confusing to you, thus let me show you my codes.
I have 2 types defined under the types tab in Toad. One of them is an object type:
CREATE OR REPLACE
TYPE R_TYPE AS OBJECT(sqn number,firstname VARCHAR2(30), lastname VARCHAR2(30));
Other one is collection type which is using the object type created above:
CREATE OR REPLACE
TYPE tr_type AS TABLE OF r_type;
Then I create a package:
CREATE OR REPLACE PACKAGE MYPACK_PKG IS
TYPE MY_REF_CURSOR IS REF CURSOR;
PROCEDURE MY_PROC(r_cursor OUT MY_REF_CURSOR);
END MYPACK_PKG;
Package Body:
CREATE OR REPLACE PACKAGE BODY MYPACK_PKG AS
PROCEDURE MY_PROC(r_cursor OUT MY_REF_CURSOR) AS
rcur MYPACK_PKG.MY_REF_CURSOR;
sql_stmt VARCHAR2(1000);
l_rarray tr_type := tr_type();
l_rec r_type;
BEGIN
sql_stmt := 'SELECT 1,e.first_name,e.last_name FROM hr.employees e ';
OPEN rcur FOR sql_stmt;
LOOP
fetch rcur into l_rec;
exit when rcur%notfound;
l_rarray := tr_type( l_rec );
END LOOP;
CLOSE rcur;
--OPEN r_cursor FOR SELECT * FROM TABLE(cast(l_rarray as tr_type) );
END MY_PROC;
END MYPACK_PKG;
I commented out the last line where I open ref cursor. Because it's causing another error when I run the procedure in Toad's SQL Editor, and it is the second question that I will ask.
And lastly I run the code in Toad:
variable r refcursor
declare
r_out MYPACK_PKG.MY_REF_CURSOR;
begin
MYPACK_PKG.MY_PROC(r_out);
:r := r_out;
end;
print :r
There I get the ora-00932 error.
The way you are using the REF CURSOR is uncommon. This would be the standard way of using them:
SQL> CREATE OR REPLACE PACKAGE BODY MYPACK_PKG AS
2 PROCEDURE MY_PROC(r_cursor OUT MY_REF_CURSOR) AS
3 BEGIN
4 OPEN r_cursor FOR SELECT e.empno,e.ENAME,null FROM scott.emp e;
5 END MY_PROC;
6 END MYPACK_PKG;
7 /
Corps de package crÚÚ.
SQL> VARIABLE r REFCURSOR
SQL> BEGIN
2 MYPACK_PKG.MY_PROC(:r);
3 END;
4 /
ProcÚdure PL/SQL terminÚe avec succÞs.
SQL> PRINT :r
EMPNO ENAME N
---------- ---------- -
7369 SMITH
7499 ALLEN
7521 WARD
7566 JONES
7654 MARTIN
[...]
14 ligne(s) sÚlectionnÚe(s).
I'm not sure what you are trying to accomplish here, you're fetching the ref cursor inside the procedure and then returning another ref cursor that will have the same data. I don't think it's necessary to fetch the cursor at all in the procedure. Let the calling app do the fetching (here the fetching is done by the print).
Update: why are you getting the unhelpful error message?
You're using a cursor opened dynamically and I think that's part of the reason you are getting the unhelpful error message. If we use fixed SQL the error message is different:
SQL> CREATE OR REPLACE PACKAGE BODY MYPACK_PKG AS
2 PROCEDURE MY_PROC(r_cursor OUT MY_REF_CURSOR) AS
3 TYPE type_rec IS RECORD (qn number,
4 firstname VARCHAR2(30),
5 lastname VARCHAR2(30));
6 lt_record type_rec; /* Record type */
7 lt_object r_type; /* SQL Object type */
8 BEGIN
9 OPEN r_cursor FOR SELECT e.empno,e.ENAME,null FROM scott.emp e;
10 FETCH r_cursor INTO lt_record; /* This will work */
11 FETCH r_cursor INTO lt_object; /* This won't work in 10.2 */
12 END MY_PROC;
13 END MYPACK_PKG;
14 /
Package body created
SQL> VARIABLE r REFCURSOR
SQL> BEGIN
2 MYPACK_PKG.MY_PROC(:r);
3 END;
4 /
BEGIN
*
ERREUR Ó la ligne 1 :
ORA-06504: PL/SQL: Return types of Result Set variables or query do not match
ORA-06512: at "APPS.MYPACK_PKG", line 11
ORA-06512: at line 2
I outlined that currently in 10.2 you can fetch a cursor into a PLSQL record but not in a SQL Object.
Update: regarding the PLS-00306: wrong number or types of arguments
l_rarray is a NESTED TABLE, it needs to be initialized and then extended to be able to store elements. For example:
SQL> CREATE OR REPLACE PACKAGE BODY MYPACK_PKG AS
2 PROCEDURE MY_PROC(r_cursor OUT MY_REF_CURSOR) AS
3 lr_array tr_type := tr_type(); /* SQL Array */
4 BEGIN
5 FOR cc IN (SELECT e.empno, e.ENAME, NULL lastname
6 FROM scott.emp e) LOOP
7 lr_array.extend;
8 lr_array(lr_array.count) := r_type(cc.empno,
9 cc.ename,
10 cc.lastname);
11 /* Here you can do additional procedural work on lr_array */
12 END LOOP;
13 /* then return the result set */
14 OPEN r_cursor FOR SELECT * FROM TABLE (lr_array);
15 END MY_PROC;
16 END MYPACK_PKG;
17 /
Corps de package crÚÚ.
SQL> print r
SQN FIRSTNAME LASTNAME
---------- ------------------------------ -----------
7369 SMITH
7499 ALLEN
7521 WARD
[...]
14 ligne(s) sÚlectionnÚe(s).
For further reading you can browse the documentation for PL/SQL collections and records.

How can we define output parameter size in stored procedure?

How can we define output parameter size in stored procedure?
You can't. Of course, you are in control of how much data you put into the OUT parameter in the stored procedure. If you want you can create a sized local variable to hold the data and then assign the value of that variable to the OUT parameter.
The calling program determines the size of the variable that receives the OUT parameter.
Here is a simple package which declares and uses a subtype:
SQL> create or replace package my_pkg as
2 subtype limited_string is varchar2(10);
3 procedure pad_string (p_in_str varchar
4 , p_length number
5 , p_out_str out limited_string);
6 end my_pkg;
7 /
Package created.
SQL> create or replace package body my_pkg as
2 procedure pad_string
3 (p_in_str varchar
4 , p_length number
5 , p_out_str out limited_string)
6 as
7 begin
8 p_out_str := rpad(p_in_str, p_length, 'A');
9 end pad_string;
10 end my_pkg;
11 /
Package body created.
SQL>
However, if we call PAD_STRING() in such a way that the output string exceeds the subtype's precision it still completes successfully. Bother!
SQL> var out_str varchar2(128)
SQL>
SQL> exec my_pkg.pad_string('PAD THIS!', 12, :out_str)
PL/SQL procedure successfully completed.
SQL>
SQL> select length(:out_str) from dual
2 /
LENGTH(:OUT_STR)
----------------
12
SQL>
This is annoying but it's the way PL/SQL works so we have to live with it.
The way to resolve the situaton is basically to apply DBC principles and validate our parameters. So, we can assert business rules against the inputs like this:
SQL> create or replace package body my_pkg as
2 procedure pad_string
3 (p_in_str varchar
4 , p_length number
5 , p_out_str out limited_string)
6 as
7 begin
8 if length(p_in_str) + p_length > 10 then
9 raise_application_error(
10 -20000
11 , 'Returned string cannot be longer than 10 characters!');
12 end if;
13 p_out_str := rpad(p_in_str, p_length, 'A');
14 end pad_string;
15 end my_pkg;
16 /
Package body created.
SQL>
SQL> exec my_pkg.pad_string('PAD THIS!', 12, :out_str)
BEGIN my_pkg.pad_string('PAD THIS!', 12, :out_str); END;
*
ERROR at line 1:
ORA-20000: Returned string cannot be longer than 10 characters!
ORA-06512: at "APC.MY_PKG", line 9
ORA-06512: at line 1
SQL>
Or we can assert business rules against the output like this:
SQL> create or replace package body my_pkg as
2 procedure pad_string
3 (p_in_str varchar
4 , p_length number
5 , p_out_str out limited_string)
6 as
7 l_str limited_string;
8 begin
9 l_str := rpad(p_in_str, p_length, 'A');
10 p_out_str := l_str;
11 end pad_string;
12 end my_pkg;
13 /
Package body created.
SQL>
SQL> exec my_pkg.pad_string('PAD THIS!', 12, :out_str)
BEGIN my_pkg.pad_string('PAD THIS!', 12, :out_str); END;
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at "APC.MY_PKG", line 9
ORA-06512: at line 1
SQL>
In most scenarios we should do both. This is the polite way to build interfaces, because it means other routines can call our procedures with the confidence that they will return the values they say they will.
You could use a subtype in a package header and type check that in the body...
CREATE OR REPLACE PACKAGE my_test
AS
SUBTYPE my_out IS VARCHAR2( 10 );
PROCEDURE do_something( pv_variable IN OUT my_out );
END;
/
CREATE OR REPLACE PACKAGE BODY my_test
AS
PROCEDURE do_something( pv_variable IN OUT my_out )
IS
lv_variable my_out;
BEGIN
-- Work on a local copy of the variable in question
lv_variable := 'abcdefghijklmnopqrstuvwxyz';
pv_variable := lv_variable;
END do_something;
END;
/
Then when you run this
DECLARE
lv_variable VARCHAR2(30);
BEGIN
my_test.do_something( lv_variable );
DBMS_OUTPUT.PUT_LINE( '['||lv_variable||']');
END;
/
You would get the error
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
Seems to go against the spirit of using an out parameter, but after Tony's comment this was the only thing I could think of to control data within the called code.

Resources