ORA-06502: PL/SQL: numeric or value error: character to number conversion error appears on the first call - oracle

I have the below pl/sql procedure
PROCEDURE insert_p(
p_batch_rec IN ra_batches%rowtype,
p_batch_id OUT NOCOPY ra_batches.batch_id%type,
p_name OUT NOCOPY ra_batches.name%type
)
batch_id is NUMBER(18,0) and p_name is VARCHAR2(50 CHAR)
I'm calling the procedure with
insert_p (l_batch_rec, p_batch_id, p_name);
where p_batch_id:=NULL and p_name:=NULL
I get the conversion error only on the first time I run the procedure. If I run again without changes, it runs fine. To reproduce the error, I disconnect and connect again.
Any ideas why does this error come and how should I resolve the same???

Does the error happen in the initialization part of a package that is used by the function?
You should be able to easily find exactly where the error happens. By default, Oracle will display the object and the line number of the error. (Although, to my great frustration, I find that it is very common for people to write when others then [poor logging that throws out line number].)
SQL> --Create package
SQL> create or replace package test_package is
2 procedure test_procedure;
3 conversion_error number;
4 end;
5 /
Package created.
SQL> --Create package body. Note the initialization part that will fail.
SQL> create or replace package body test_package is
2 procedure test_procedure is
3 begin
4 null;
5 end;
6 begin
7 conversion_error := 'This is not a number';
8 end;
9 /
Package body created.
SQL> --This will fail the first time
SQL> begin
2 test_package.test_procedure;
3 end;
4 /
begin
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character to number conversion error
ORA-06512: at "JHELLER.TEST_PACKAGE", line 7
ORA-06512: at line 2
SQL> --But will now work until you reconnect, or run DBMS_SESSION.RESET_PACKAGE.
SQL> begin
2 test_package.test_procedure;
3 end;
4 /
PL/SQL procedure successfully completed.
SQL>

Related

What actually PROMPT<?> syntax do in oracle procedure?

So, in this code what exactly PROMPT syntax do?
PROMPT create or replace procedure abc (p_name, p_id)
AUTHID CURRENT_USER
as
begin
dbms_output.put_line('hi');
end;
PROMPT has a meaning if you run some code in SQL*Plus (not many people do that nowadays). It displays text what follows that keyword.
SQL> help prompt
PROMPT
------
Sends the specified message or a blank line to the user's screen.
PRO[MPT] [text]
SQL> prompt hello there!
hello there!
SQL>
In your case, it produces unwanted result as it displays the create procedure (instead of creating it):
SQL> PROMPT create or replace procedure abc (p_name, p_id)
create or replace procedure abc (p_name, p_id)
SQL> AUTHID CURRENT_USER
SP2-0734: unknown command beginning "AUTHID CUR..." - rest of line ignored.
SQL> as
SP2-0042: unknown command "as" - rest of line ignored.
SQL> begin
2 dbms_output.put_line('hi');
3 end;
4 /
hi
PL/SQL procedure successfully completed.
SQL>
You got the result, but just as pure accident as
begin
dbms_output.put_line('hi');
end;
was a valid PL/SQL block.
Code you posted (without prompt) is invalid:
SQL> create or replace procedure abc (p_name, p_id)
2 AUTHID CURRENT_USER
3 as
4 begin
5 dbms_output.put_line('hi');
6 end;
7 /
Warning: Procedure created with compilation errors.
SQL> show err
Errors for PROCEDURE ABC:
LINE/COL ERROR
-------- -----------------------------------------------------------------
1/22 PLS-00103: Encountered the symbol "," when expecting one of the
following:
in out <an identifier> <a double-quoted delimited-identifier>
... long double ref char time timestamp interval date binary
national character nchar
3/1 PLS-00103: Encountered the symbol "AS" when expecting one of the
following:
with authid cluster order deterministic parallel_enable
pipelined result_cache
6/4 PLS-00103: Encountered the symbol "end-of-file" when expecting
one of the following:
end not pragma final instantiable order overriding static
member constructor map
SQL>
What does it mean? Procedure's parameters have to have datatype:
SQL> create or replace procedure abc (p_name in varchar2, p_id in number)
2 AUTHID CURRENT_USER
3 as
4 begin
5 dbms_output.put_line('hi');
6 end;
7 /
Procedure created.
SQL> exec abc(null, null);
hi
PL/SQL procedure successfully completed.
SQL>

when try to excure procedure it said compliation error in oracle?

I try to write select procedure in oracle.but it compile success, when I try to execute it given error.
set serveroutput on;
CREATE OR REPLACE PROCEDURE retrieve_decrypt(
custid in NUMBER,
column_name in VARCHAR2,
test_value OUT VARCHAR2
)
AS
BEGIN
-- enc_dec.decrypt(column_name,password) into test_value from employees where custid=5;
COMMIT;
END;
/
set serveroutput on;
EXEC retrieve_decrypt(5,'creditcardno');
the error says ,
This is your procedure:
SQL> create or replace procedure retrieve_decrypt
2 (custid in number,
3 column_name in varchar2,
4 test_value out varchar2
5 )
6 as
7 begin
8 -- your code goes here
9 null;
10 end;
11 /
Procedure created.
SQL>
This is how you call it (and get the error):
SQL> exec retrieve_decrypt(5, 'creditcardno');
BEGIN retrieve_decrypt(5, 'creditcardno'); END;
*
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'RETRIEVE_DECRYPT'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
SQL>
The cause of the error is:
the procedure contains 3 parameters:
2 of them are IN - you provided their values
1 of them is OUT - you didn't provide it and got the error
Here's what you should have done: as the 3rd parameter is OUT, you'll have to DECLARE it:
SQL> declare
2 l_out varchar2(20);
3 begin
4 retrieve_decrypt(5, 'creditcardno', l_out);
5 end;
6 /
PL/SQL procedure successfully completed.
SQL>
EXEC you used is a SQL*Plus command so it might not work everywhere; DECLARE-BEGIN-END block will so I'd suggest you use it.
Alternatively, in SQL*Plus, it could be rewritten as
SQL> var l_out varchar2
SQL>
SQL> exec retrieve_decrypt(5, 'creditcardno', :l_out);
PL/SQL procedure successfully completed.
SQL>
but - once again - you'd better use DECLARE-BEGIN-END PL/SQL block.
The initial error is:
wrong number or types of arguments in call to 'RETRIEVE_DECRYPT'
The procedure requires 3 parameters. You are only passing 2 (or apparently only 1, in the attempt that generated the error message shown).
Why do you also see the message "Usually a PL/SQL compilation error"? The EXEC command in SQLPlus creates a PL/SQL block containing the text you provide, and sends that to Oracle for execution. Oracle attempts to compile that PL/SQL block (just like it compiles the procedure when you create it). In this case, the compilation fails because of the mismatch in the number of arguments.

Oracle procedure compiling successfully but show errors

Using Oracle SQL Developer I created a simple procedure. The procedure compiles successfully, but when I type the command:
execute CMPPROJECTPROCSELECT();
BEGIN CMPPROJECTPROCSELECT(); END;
I get the following errors:
Error starting at line : 1 in command -
execute CMPPROJECTPROCSELECT()
Error report -
ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'CMPPROJECTPROCSELECT'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
Error starting at line : 2 in command -
BEGIN CMPPROJECTPROCSELECT(); END;
Error report -
ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'CMPPROJECTPROCSELECT'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
Please help me to solve this. I know it's a small error. Also I have specified the data types, declarations of names correctly.
My procedure code is
CREATE OR REPLACE PROCEDURE CMPPROJECTPROCSELECT(
p_projectname IN VARCHAR2,
p_description OUT VARCHAR2)
IS
BEGIN
SELECT DESCRIPTION
INTO p_description
FROM CMPPROJECT
WHERE PROJECTNAME = p_projectname;
EXCEPTION
WHEN NO_DATA_FOUND THEN
p_description:= NULL;
COMMIT;
END CMPPROJECTPROCSELECT;
execute CMPPROJECTPROCSELECT();
BEGIN CMPPROJECTPROCSELECT();
END;
EXECUTE is SQL*Plus command.
You are not passing the required parameters to the procedure. You have declared two parameters for your procedure:
p_projectname IN VARCHAR2,
p_description OUT VARCHAR2
So, you need to declare the required parameters and then pass it to the procedure:
DECLARE
proj_desc VARCHAR2(2000);
BEGIN
CMPPROJECTPROCSELECT('project_name', proj_desc);
-- use the OUT value of proj_desc later
END;
/
On a side note, you do not need COMMIT at all. It is required to permanently commit a DML and has nothing to do with a SELECT ..INTO clause.
SELECT DESCRIPTION INTO p_description FROM CMPPROJECT WHERE PROJECTNAME = p_projectname;
EXCEPTION
WHEN NO_DATA_FOUND THEN
p_description:= NULL;
COMMIT; -- You don't need COMMIT at all
UPDATE A working demonstration:
In PL/SQL:
SQL> CREATE OR REPLACE PROCEDURE get_emp(
2 p_ename IN VARCHAR2,
3 p_job OUT VARCHAR2)
4 IS
5 BEGIN
6 SELECT job INTO p_job FROM emp WHERE ename = p_ename;
7 END;
8 /
Procedure created.
SQL> sho err
No errors.
SQL> set serveroutput on
SQL> DECLARE
2 job VARCHAR2(20);
3 BEGIN
4 get_emp('SCOTT',JOB);
5 DBMS_OUTPUT.PUT_LINE('The output is '||job);
6 END;
7 /
The output is ANALYST
PL/SQL procedure successfully completed.
In SQL*Plus:
SQL> VARIABLE JOB VARCHAR2(20);
SQL> EXECUTE get_emp('SCOTT', :JOB);
PL/SQL procedure successfully completed.
SQL> PRINT JOB;
JOB
--------------------------------
ANALYST

How can I get the procedure/function name where an exception occurs, in PLSQL?

How can I get a procedure/function name where an exception occurs in PLSQL?
I need this to create a log of the procedures that have problems in a package.
Unfortunately there is no way to get a stored procedure name, that is wrapped in a package, at run time. Any method, whether it $$PLSQL_UNIT inquiry directive or FORMAT_ERROR_BACKTRACE function of dbms_utility package, that allows you to do that in a case of a stand-alone stored procedure will always give you the anonymous block instead of a name in a case of a stored procedure that is wrapped in the package. Hence your only choice is to capture a package name and the line number on which an error has occurred by using dbms_utility.format_error_backtrace for example.
SQL> create or replace package some_pkg
2 as
3 procedure some_proc;
4 end;
5 /
Package created
SQL>
SQL> create or replace package body some_pkg
2 as
3 procedure Some_Proc
4 is
5 l_var number;
6 begin
7 l_var := 1/0;
8 exception
9 when others
10 then dbms_output.put_line(dbms_utility.format_error_backtrace);
11 end;
12 end;
13 /
Package body created
SQL> exec some_pkg.some_proc;
ORA-06512: at "HR.SOME_PKG", line 7
Did u mean get all procedures that has 'exception' in their source ?
if so then :
select distinct t.name from user_source t
where upper(t.text) like '%EXCEPTION%' or
upper(t.text) like '%RAISE_APPLICATION_ERROR%';
I hope it helps you :)

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