Compilation errors on stored procedure - oracle

I am typically a SQL Server developer however am now working with a system that uses Oracle. I have created a new procedure and am getting a runtime error. Here is the procedure:
CREATE OR REPLACE PROCEDURE CHK_LASTAPPTIME
(
LASTAPPTIME OUT VARCHAR2
)
IS
v_appappid varchar2(20) null;
v_lastapptime number null;
BEGIN
select max(APPID) into v_appappid from applicationtable;
select trunc(v_lastapptime = (((sysdate - capturedate) * 24)) * 60) from applicationtable where APPID = v_appappid;
LASTAPPTIME := to_char(v_lastapptime);
END CHK_LASTAPPTIME;
Here is the error that I am getting:
SQL> var x varchar2;
SQL> exec CHK_LASTAPPTIME(:x);
BEGIN CHK_LASTAPPTIME(:x); END;
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at "CAPDEV.CHK_LASTAPPTIME", line 19
ORA-06512: at line 1

Your proecedure doesn't have 19 lines, so the message is odd, or you've shown different code to what you're actually running. Since what you've shown doesn't compile I'm assuming you've tried to cut it down for the question, and I'll also assume your actual procedure is valid and does what you want.
The problem is in your run-time variable declaration. You haven't specified a size for x, so it uses a default. On my DB, in SQL*Plus that seems to allow three characters but errors with four or more:
var x varchar2;
exec :x := 'a';
PL/SQL procedure successfully completed.
exec :x := 'ab';
PL/SQL procedure successfully completed.
exec :x := 'abc';
PL/SQL procedure successfully completed.
exec :x := 'abcd';
BEGIN :x := 'abcd'; END;
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at line 1
The limit might be related to your character set, perhaps. SQL Developer allows more by default.
Anyway, specify the size for your variable:
var x varchar2(30);
exec CHK_LASTAPPTIME(:x);
You seem to be generating a number in your procedure, and then returning that as a string. Using the same data type would make this a bit simpler.

Related

Call Oracle stored procedures from a main oracle stored procedure (syntax error)

I am trying to create a main Oracle stored procedure, calling other Oracle stored procedures. I am getting a syntax error in Toad.
The environment is Windows Server 2012R2 and the Oracle edition is 12.1.0.
The main stored procedure is simple:
CREATE OR REPLACE PROCEDURE TESTDB.MAIN
(
ID IN NUMBER
)
IS
BEGIN
CALL PROCEDURE1(ID);
CALL PROCEDURE2(ID);
CALL PROCEDURE3(ID);
CALL PROCEDURE4(ID);
END;
I am getting a syntax error while compiling for each procedure:
PLS-00103: Encountered the symbol "PROCEDURE1" when
expecting one of the following:
:= . ( # % ; The symbol ":=" was substituted for
"PROCEDURE1" to continue.
What is the correct syntax in order to call the procedures from one central procedure?
You have to remove CALL, that can only be used
to execute a routine […] from within SQL
BEGIN
PROCEDURE1(ID);
PROCEDURE2(ID);
PROCEDURE3(ID);
PROCEDURE4(ID);
END;
For example:
SQL> create or replace procedure proc(n IN OUT number) is begin n := 10; end;
2 /
Procedure created.
SQL> var x number
SQL> call proc(:x);
Call completed.
SQL> print :x
X
----------
10
SQL> declare
2 y number;
3 begin
4 call proc(y);
5 end;
6 /
call proc(y);
*
ERROR at line 4:
ORA-06550: line 4, column 8:
PLS-00103: Encountered the symbol "PROC" when expecting one of the following:
:= . ( # % ;
The symbol ":=" was substituted for "PROC" to continue.
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.

Error: ORA-06502: PL/SQL: numeric or value error: host bind array too small

I want to understand when this oracle error occurs 'Error: ORA-06502: PL/SQL: numeric or value error: host bind array too small'
I have a plsql block and it has a normal annonymus block which has DBMS_output.put_line and also has DBMS_output.put in a for loop and in the code its calls another package in for loop itself and the out variables like success( as S) and errormessage (as err_msg) of package are displayed using DBMS_output.put and the out put gets printed for few records but suddenly a above error occurs and blocks gets completed don't how this happemed. Can any one explain why such error occurs.
The error occurs on the client-side, not on the server-side, so it's an error with specific versions of sqlplus. It happens when sqlplus utility tries to read the dbms_output buffer from the server-side to the client-side buffer, and the buffer contains a string that is more than 255 characters long. So error happens when:
you are using sqlplus with version less than 10.2 and the version of Database server is 10.2 or higher. For example:
client is 10.1.0.5 and server is 12.2.9
client is 10.1.0.5 and server is 10.2.0.5
client is 10.1.0.5 and server is 11.2.0.1
the serveroutput on option is set
you have put a line with more than 255 characters into the dbms_output buffer.
Please, note that if your server is 10.1.0.5 or less (9.2.0.8) you would get different error: ORA-20000: ORU-10028: line length overflow, limit of 255 chars per line.
Demo
Put 256 characters and we get the error:
SET SERVEROUTPUT ON
begin
dbms_output.put_line(a => rpad('1',256,'1'));
end;
/
ERROR:
ORA-06502: PL/SQL: numeric or value error: host bind array too small
ORA-06512: at line 1
Or you can do it in a slightly different way:
SET SERVEROUTPUT ON
begin
dbms_output.put(a => rpad('1',200,'1'));
dbms_output.put(a => rpad('1',200,'1'));
dbms_output.put_line('');
end;
/
ERROR:
ORA-06502: PL/SQL: numeric or value error: host bind array too small
ORA-06512: at line 1
Put 255 characters and it' ok we get the output:
SET SERVEROUTPUT ON
begin
dbms_output.put_line(a => rpad('1',255,'1'));
end;
/
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111
How to solve
Option 1:
Oracle fixed the error in the 10.2 release, so if you upgrade your server-side and the client-side components to at least 10.2.0.5, the error will be fixed.
Option 2:
If you absolutely have to use 10.1 version or older versions of sqlplus (and version of Database is 10.2 or higher) and you cannot rewrite your pl/sql code that generates long characters string, then you can work around this bug using dbms_output.get_lines (or dbms_output.get_line) procedures:
SET SERVEROUTPUT OFF
begin
-- enable the server-side buffer. When SET SERVEROUTPUT ON sqlplus does it automatically.
-- Now we do it manually.
dbms_output.enable(1000000);
dbms_output.put_line(a => rpad('1',300,'1'));
end;
/
PL/SQL procedure successfully completed.
Then use this block just to get the content of the buffer:
variable l_cursor REFCURSOR
set autoprint on
declare
-- Then use this block to get the contents of the buffer.
l number:=10000;
l_array DBMSOUTPUT_LINESARRAY;
begin
dbms_output.get_lines(l_array,l);
open :l_cursor for select * from table(l_array);
end;
/
PL/SQL procedure successfully completed.
COLUMN_VALUE
--------------------------------------------------------------------------------
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111
usually this error will occur when you either try to set a variable with too big a value. for instance.
v_number number(2);
BEGIN
v_number := 100;
END;
or when you try to save text into a number variable
v_number number(2);
BEGIN
v_number := 'a';
END;
see here for more info: https://www.techonthenet.com/oracle/errors/ora06502.php

Why do I get an error as I try to call a procedure?

I created a procedure named greet as :
create procedure greet(message in char(50))
as
begin
dbms_output.put_line('Greet Message : ' || message);
end;
The procedure compiled successfully but when I try to call it as :
execute greet('Hey ! This is a self created procedure :)');
I get an error :
execute greet('Hey ! This is a self created procedure :)')
Error report:
ORA-06550: line 1, column 7:
PLS-00905: object SUHAIL.GREET is invalid
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:
What error is it ? Why do I get it ?
Note : 'suhail' is name of the current user connected to oracle server
I don't believe that your procedure compiled successfully. When I try to compile it on my system, I get syntax errors
SQL> create procedure greet(message in char(50))
2 as
3 begin
4 dbms_output.put_line('Greet Message : ' || message);
5 end;
6 /
Warning: Procedure created with compilation errors.
SQL> sho err
Errors for PROCEDURE GREET:
LINE/COL ERROR
-------- -----------------------------------------------------------------
1/32 PLS-00103: Encountered the symbol "(" when expecting one of the
following:
:= ) , default varying character large
The symbol ":=" was substituted for "(" to continue.
If I resolve the syntax errors (you cannot specify a length for an input parameter), it works
SQL> ed
Wrote file afiedt.buf
1 create or replace procedure greet(message in char)
2 as
3 begin
4 dbms_output.put_line('Greet Message : ' || message);
5* end;
SQL> /
Procedure created.
SQL> set serveroutput on;
SQL> execute greet('Hey ! This is a self created procedure :)');
Greet Message : Hey ! This is a self created procedure :)
PL/SQL procedure successfully completed.
I would be shocked if you really wanted the input parameter to be declared as CHAR. Almost always, you should use VARCHAR2 for character strings. It is exceptionally rare to come across a case where you really want the blank-padding semantics of a CHAR.
this is working dude;
create or replace
procedure greet(message in char)
as
begin
dbms_output.put_line('Greet Message : ' || message);
end;
see main property of char datatype is is the length of input data is less than the size you specified it'll add blank spaces.this case is not happened for varchar2.
in procedure above mentioned char property is violated so it's almost treat like varchar2. so if you remove size of input parameter it will work and also char support maximum length of input.

MD5 in Oracle (DBMS_OBFUSCATION_TOOLKIT.MD5)

I'm trying to compose a function to obtain MD5 hashes from bits I've gathered here and there. I want to obtain the lower-case hexadecimal representation of the hash. I have this so far:
CREATE OR REPLACE FUNCTION MD5 (
CADENA IN VARCHAR2
) RETURN DBMS_OBFUSCATION_TOOLKIT.VARCHAR2_CHECKSUM
AS
BEGIN
RETURN LOWER(
RAWTOHEX(
UTL_RAW.CAST_TO_RAW(
DBMS_OBFUSCATION_TOOLKIT.MD5(INPUT_STRING => CADENA)
)
)
);
END;
I'm not sure about the return type of the function. DBMS_OBFUSCATION_TOOLKIT.VARCHAR2_CHECKSUM looks like the appropriate choice and as far as I can tell it works as expected but the package definition for dbms_obfuscation_toolkit as displayed by SQL Developer shows this:
SUBTYPE varchar2_checksum IS VARCHAR2(16);
The output has 32 characters so I must be doing something wrong. My questions:
What's the correct type for the RETURN statement?
Am I doing unnecessary conversions to calculate the hash?
Here you go:
create or replace function getMD5(
in_string in varchar2)
return varchar2
as
cln_md5raw raw(2000);
out_raw raw(16);
begin
cln_md5raw := utl_raw.cast_to_raw(in_string);
dbms_obfuscation_toolkit.md5(input=>cln_md5raw,checksum=>out_raw);
-- return hex version (32 length)
return rawtohex(out_raw);
end;
The 32 length is because it is a hex representation of the raw(16) value. Or, modify above to output the raw version and store the raw in a RAW column (less space used, but you'll be doing future rawtohex and hextoraw conversions, believe me).
Cheers
It's a peculiarity of Oracle PL/SQL that stored procedure parameters and function return types cannot be limited. That is, we cannot have a procedure with a signature like this:
SQL> create or replace procedure my_proc (p1 in varchar2(30))
2 is
3 begin
4 null;
5 end;
6 /
Warning: Procedure created with compilation errors.
SQL> show error
Errors for PROCEDURE MY_PROC:
LINE/COL ERROR
-------- -----------------------------------------------------------------
1/34 PLS-00103: Encountered the symbol "(" when expecting one of the
following:
:= . ) , # % default character
The symbol ":=" was substituted for "(" to continue.
SQL> create or replace procedure my_proc (p1 in varchar2)
2 is
3 begin
4 null;
5 end;
6 /
Procedure created.
SQL>
Sure we can define the procedure's parameter using a SUBTYPE but Oracle will ignore it. Same goes for function return types...
SQL> create or replace package my_subtypes as
2 subtype ltd_string is varchar2(30);
3 end;
4 /
Package created.
SQL> create or replace function my_func return my_subtypes.ltd_string
2 is
3 begin
4 return lpad('a', 4000, 'a');
5 end;
6 /
Function created.
SQL> select length(my_func) from dual
2 /
LENGTH(MY_FUNC)
---------------
4000
SQL>
The only way of limiting parameters and return types is to declare variables using subtypes within the stored procedure. Use the variables within the package, and assign them to the OUT paramters (or RETURN the variable for functions).
Which is a long-winded way of saying, you can use DBMS_OBFUSCATION_TOOLKIT.VARCHAR2_CHECKSUM in your code confident that it won't prevent your function returning 32 characters.
However, it will confuse developers who will lookup the SUBTYPE declaration. In the worst case these people will use the subtype to declare their own working variables with the following tragic result:
SQL> declare
2 v my_subtypes.ltd_string;
3 begin
4 v := my_func;
5 end;
6 /
declare
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at line 4
SQL>
So, it is better not to use an inappropriate subtype. Instead declare your own.

Resources