Oracle 11g - Passing boolean to stored procedure - stored-procedures

I am trying to create a stored procedure with boolean input parameter:-
Step 1: I have created a table like below
CREATE TABLE STOREBOOL ( BOOLVAL NUMBER(1));
Step 2: I created a stored procedure
Based on the following link: http://docs.oracle.com/cd/F49540_01/DOC/java.815/a64685/tips3.htm#1005343 created a procedure
CREATE OR REPLACE PROCEDURE boolProc(x boolean)
AS
BEGIN
INSERT INTO storebool("boolval") VALUES(x);
COMMIT;
END;
Output is:-
Warning: Procedure created with compilation errors.
Similarly created a second procedure:
CREATE OR REPLACE PROCEDURE boolWrap(x int)
AS
BEGIN
IF (x=1) THEN
boolProc(TRUE);
ELSE
boolProc(FALSE);
END IF;
END;
Output is:-
Warning: Procedure created with compilation errors.
Step 3: Executing the code
BEGIN
boolWrap(1);
END;
/
It is showing the following error:
boolWrap(1);
*
ERROR at line 2:
ORA-06550: line 2, column 1
PLS-00905: object SCOTT.BOO
ORA-06550: line 2, column 1
PL/SQL: Statement ignored
How do i run it properly?

Did you notice the "created with compilation errors" messages? You can see what the errors were immediately after you see that with show errors, or by querying the user_errors view.
In the first procedure you're dong this:
INSERT INTO storebool("boolval") VALUES(x);
... which has two problems: (a) you don't have a column called "boolval"; it was created unquoted as BOOLVAL so either refer to it unquoted, or quoted but in uppercase as it appears in the data dictionary; and (b) you're trying to set a number column to a boolean value. Oracle SQL doesn't have a boolean type, but there is no implicit conversion available. You need to define what number represents TRUE, and what represents FALSE, and then insert that number instead of the boolean x argument. So you'd see errors like:
4/46 PLS-00382: expression is of wrong type
4/28 PL/SQL: ORA-00904: "boolval": invalid identifier
The boolWrap can't compile because boolProc isn't valid.
Your boolProc and boolWrap procedures are reversed really; you want the 'real' procedure to take a number argument, and the wrapper to take a boolean and convert that to a number to call the real one.
This might make more sense:
CREATE TABLE STOREBOOL (BOOLVAL NUMBER(1),
CONSTRAINT BOOLCHECK CHECK (BOOLVAL IN (0,1))
);
CREATE OR REPLACE PROCEDURE boolProc(p_bool_num number)
AS
BEGIN
INSERT INTO storebool(boolval) VALUES (p_bool_num);
END;
/
CREATE OR REPLACE PROCEDURE boolWrap(p_bool boolean)
AS
l_bool_num number;
BEGIN
IF p_bool THEN
boolProc(1);
ELSE
boolProc(0);
END IF;
END;
/
Then you can call boolProc with a number argument, or boolWrap with a boolean argument:
BEGIN
boolProc(1);
END;
/
BEGIN
boolWrap(false);
END;
/
select * from storebool;
BOOLVAL
----------
1
0

Related

DB2 LUW - Get Error Line in Stored Procedure

I'm trying to determine the line in a stored procedure or the last SQL-statement which is causing an error. As a workaround I'm using temporary variables which I manually set to determine in which part of my stored procedure an error occurs.
See the following:
-- Create an ErrorLog table
Create Table SCHEMA.ErrorLog_lrc_test
(
ErrSQLCODE Integer ,
Codepart Char(1),
Type Char(1) ,
MsgText VarChar(1024));
CREATE OR REPLACE PROCEDURE SCHEMA.test_error(IN divisor INT)
LANGUAGE SQL
BEGIN
-- Define variables
DECLARE codepart_var Char(1);
DECLARE test_INT INT;
-- Define sqlcode
DECLARE SQLCODE INTEGER;
--Define Error-Handler
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
BEGIN
INSERT INTO SCHEMA.ErrorLog_lrc_test(ErrSQLCODE, Codepart, TYPE, MsgText)
VALUES(SQLCODE, codepart_var, 'E', SYSPROC.SQLERRM(SQLCODE));
END;
--Define Warning-Handler
DECLARE CONTINUE HANDLER FOR SQLWARNING, NOT FOUND
BEGIN
INSERT INTO SCHEMA.ErrorLog_lrc_test(ErrSQLCODE, Codepart, TYPE, MsgText)
VALUES(SQLCODE, codepart_var, 'W', SYSPROC.SQLERRM(SQLCODE));
END;
-- Set temporary variable to 'a' to get part of code where error occured
SET codepart_var = 'a';
-- Create Error
sELECT 1/divisor into test_INT
FROM SYSIBM.SYSDUMMY1;
SET codepart_var = 'b';
-- Create Error
sELECT 1/divisor into test_INT
FROM SYSIBM.SYSDUMMY1;
SET codepart_var = 'c';
-- Create Not Found (Sqlcode 100)
INSERT INTO SCHEMA.ErrorLog_lrc_test
SELECT NULL, NULL, NULL, NULL FROM "SYSIBM".SYSDUMMY1
WHERE 1 = 0 ;
END
call SCHEMA.test_error(0);
SELECT *
FROM SCHEMA.ErrorLog_lrc_test;
I get the following:
ERRSQLCODE
CODEPART
TYPE
MSGTEXT
-801
a
E
SQL0801N Division by zero was attempted.
-801
b
E
SQL0801N Division by zero was attempted.
100
c
W
SQL0100W No row was found for FETCH, UPDATE or DELETE; or the result of a query is an empty table.
So I am able to get the part of the code where an error or warning occurs, but it would be better to get the line or the SQL statement as I don't want to specify every part of the code with a temporary variable.
I already found this SQLCA --> sqlerrd(3): "...If an error is encountered during the compilation of an SQL routine, trigger, or dynamic compound SQL (inlined or compiled) statement, sqlerrd(3) contains the line number where the error was encountered". For now I didn't manage to make use of SQLCA variables. I don't know how to implement them in DB2 LUW in a stored procedure.
Is there another/better way to log the specific line or SQL-statement in a stored procedure which is causing an error?
My DB2 version is 10.5.0.
Thank you!
If your Db2-server platform is Linux/Unix/Windows, and you are using a recent version, then consider using DBMS_UTILITY.FORMAT_ERROR_BACKTRACE which may help you.
Documentation here. The documentation includes a worked example.
When using this for stored procedures or routines, it is wise to always create those routines with a meaningful specific name with the SPECIFIC clause on the create or replace statement. Otherwise the routine will have a system generated name which will not be meaningful to users when it appears in the output of DBMS_UTILITY.FORMAT_ERROR_BACKTRACE. There are other reasons you should always use a specific name for your routines.
The SQLCA is for calling programs (i.e. the program that calls the stored procedure).

Compilation failed: Encountered the symbol "," when expecting one of the following: := ; not null default character

I am facing this error:
Compilation failed,line 3 (01:07:19)
PLS-00103: Encountered the symbol "," when expecting one of the
following: := ; not null default character
And my Procedure is:
create or replace procedure testing
as
v_ID NUMBER;v_ASSIGNEE_NAME varchar2(55),v_EMAIL varchar2(55),v_PHONE NUMBER;v_FIELD varchar2(50);
begin
select ID,ASSIGNEE_NAME,EMAIL,PHONE,FIELD into
v_ID NUMBER;v_ASSIGNEE_NAME varchar2(55),v_EMAIL varchar2(55),v_PHONE NUMBER;v_FIELD varchar2(50);
FROM ASSIGNEE;
Quite a number of issues in this, see formatted code below. In your declaration of variables you were separating them with a comma, this needs to be a semicolon. Also in your into clause you had included the variable types. The best thing you can do is to format your code so that is easier to read and debug.
create or replace procedure testing as
v_ID NUMBER;
v_ASSIGNEE_NAME varchar2(55);
v_EMAIL varchar2(55);
v_PHONE NUMBER;
v_FIELD varchar2(50);
begin
select ID,ASSIGNEE_NAME,EMAIL,PHONE,FIELD
into v_ID NUMBER, v_ASSIGNEE_NAME, v_EMAIL, v_PHONE NUMBER, v_FIELD
FROM ASSIGNEE;
end;
There were couple of syntactical errors which was preventing you from compiling your code. Below snippet will help you.
CREATE OR REPLACE PROCEDURE testing
AS
v_ID NUMBER;
v_ASSIGNEE_NAME VARCHAR2(55);
v_EMAIL VARCHAR2(55);
v_PHONE NUMBER;
v_FIELD VARCHAR2(50);
BEGIN
SELECT ID,
ASSIGNEE_NAME,
EMAIL,
PHONE,
FIELD
INTO v_ID,
v_ASSIGNEE_NAME,
v_EMAIL,
v_PHONE,
v_FIELD
FROM ASSIGNEE;
END;

How to call a stored function from a stored procedure and store the return value

When I do this in my stored procedure:
create procedure Proc1(
startdate IN TIMESTAMP,
ENDDATE IN TIMESTAMP
)
declare test_result number --line 55
test_result:=Stored_function1(startdate,enddate,11,13); --line 56
END;
SQL Developer throws 2 errors:
PLS-00103: Encountered the symbol "TEST_RESULT" when expecting one of the following: := . ( # % ; not null range default character The symbol "." was substituted for "TEST_RESULT" to continue.
PLS-00103: Encountered the symbol "END" when expecting one of the following: begin function pragma procedure subtype type current cursor delete exists prior
Stored_function1 is user defined, takes 4 parameters, and does not belong to any package. Where did I do wrong and how do I correct it? Thanks.
Without seeing more of it it's hard to tell, but it seems you have some syntax error(s) in your procedure. No DECLARE is needed, there should be a semi-colon at the end of line 55 and a BEGIN before line 56 at the least.
Here's a basic skeleton:
Create or replace procedure my_procedure as
test_result number;
BEGIN
test_result := Stored_function1(startdate, enddate, 11, 13);
END;

pass list of values as input parameter to PL/SQL procedure

Hi I have a requirement where I get list of values to a input parameter in PL/SQL procedure. The size of the input list varies which is dynamic. How to handle this requirement any help?
CREATE OR REPLACE PACKAGE PKG_TEST AS
TYPE X IS TABLE OF VARCHAR2(30);
PROCEDURE XYZ(Y IN X);
END PKG_TEST;
/
The type can be declared as "TABLE OF" OR "VARRAY(10)";
CREATE OR REPLACE PACKAGE BODY PKG_TEST AS
PROCEDURE XYZ(Y IN X) AS
BEGIN
FOR I IN Y.FIRST..Y.LAST
LOOP
DBMS_OUTPUT.PUT_LINE('THE VALUE OF I IS'||Y(I));
END LOOP;
END;
END PKG_TEST;
/
DECLARE
BEGIN
PKG_TEST.XYZ('1','2','3','4');
END;
/
You could use a varchar parameter in sql, each value must be separated by a comma, something like this:
'value1,value2,value3,value4,...,'
So, you can read the values using the function split of sql
I hope that I understood your question

Difference of execution in SQL Developer and SQL *Plus

The following code runs good as expected in SQL Developer without any errors, but when I run the code in SQL*Plus it is throwing an error.
declare
v_num1 integer := '&a';
v_num2 integer := '&b';
v_result number;
begin
v_result := v_num1 / v_num2;
dbms_output.put_line ('v_result: '||v_result);
end;
The error raised is
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character to number conversion error
ORA-06512: at line 2
Please point out where the error I made.
Your SQL*Plus session has substitution variables turned off, so the '&a' is being treated as a literal string, and it isn't prompting you for the value. In a simplified version:
set define off
declare
i integer := to_number('&a');
begin
null;
end;
/
declare
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character to number conversion error
ORA-06512: at line 2
To fix it, turn substitution variables back on:
set define &
Then it works:
declare
i integer := to_number('&a');
begin
null;
end;
/
Enter value for a:
If I enter 1:
PL/SQL procedure successfully completed.
You don't need the quotes, or the to_number(), unless you're using group seperators (and then you'd need to supply a format model too). You can just do:
declare
i integer := &a;
begin
null;
end;
/
As you have it you're doing an unnecessary implicit string-to-number conversion.
If you haven't explicitly turned them off, then you probably have a site or user profile that is doing the set define off, among other configuration settings. it's probably doing that for a reason, but if you currently only have a site profile then you could create your own user profile to override that. Just be aware of the effect of anything you change; you may have other scripts that rely on it being off, e.g. if you have data that has ampersands and it's been disabled to prevent issues interpreting those.

Resources