PL/SQL numeric value or error: confusion with functions and procedures (Oracle PL/SQL) - oracle

I previously asked a question in stackoverflow regarding a certain function that I was having a hard time with and I found the answer when I saw the RETURN statement missing.
Now, I am dealing with a procedure that calls for the input text letters to be converted to UPPER if in the LOWER case and vice versa.
e.g IF I put in 'AbC' it should return 'aBc'
So far this is my code
CREATE OR REPLACE PROCEDURE Opposite_Case (p_string IN VARCHAR2)
IS
var_string VARCHAR2(20);
var_contain VARCHAR2(20);
i NUMBER;
BEGIN
var_string:=substr(Opposite_Case.p_string,i,1);
var_contain:= var_string || var_contain;
FOR i in 1.. length(var_string)
LOOP
BEGIN
IF var_string IN ('ABCDEFGHIJKLMNOPQRSTUVWXYZ') THEN
SELECT LOWER(var_string) INTO var_contain FROM dual;
ELSE
SELECT UPPER(var_string) INTO var_contain FROM dual;
END IF;
END;
END LOOP;
END;
/
BUT the following error is returned:
EXECUTE Opposite_Case('AbC')
begin Opposite_Case('AbC'); end;
ORA-06502: PL/SQL: numeric or value error
ORA-06512: at "SYS.OPPOSITE_CASE", line 10
ORA-06512: at line 1
Thanks in advance.
PS. This is just my 3rd day with a PL/SQL language so please bear with me.
EDIT: I got it to work finally thanks to #Satya's help. Now I get to convert them like it should but how do I output my selects in one line though?
I'm almost there. Appreciate the help a lot from this community!!
What I have so far:
SQL> EXECUTE Opposite_Case('AbC')
A
b
C
PL/SQL procedure successfully completed

You should investigate the TRANSLATE function. To use it to switch the case of the characters in your string you'd do something like the following:
SELECT TRANSLATE('AbC',
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
FROM DUAL;
which should return 'aBc'.
SQLFiddle here
Share and enjoy.

Finally found the answer! Thanks guys! (without TRANSLATE though)!
CREATE OR REPLACE PROCEDURE Opposite_Case (p_string IN VARCHAR2)
IS
var_string VARCHAR2(20);
var_contain VARCHAR2(20);
i NUMBER;
BEGIN
FOR i in 1.. length(p_string)
LOOP
BEGIN
var_string:=substr(p_string,i,1);
var_contain:= var_string;
IF var_string IN ('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z') THEN
SELECT LOWER(var_string) INTO var_contain FROM dual;
DBMS_OUTPUT.PUT(var_contain);
ELSE
SELECT UPPER(var_string) INTO var_contain FROM dual;
DBMS_OUTPUT.PUT(var_contain);
END IF;
END;
END LOOP;
dbms_output.new_line;
END;
/

Related

Returning Multiple Columns in stored procedure - ORACLE 11.2 Up

Just wondering how I go about returning multiple columns from the database with this stored proc, Thanks.
is
cursor sample_cur is --this can be your select statement
select name as today from names;
begin
for rec in sample_cur loop
-- step by step for each record you return in your cursor
dbms_output.put_line(rec.name);
end loop;
end;
Cursor can return multiple columns, for example:
procedure list_something(p_result out sys_refcursor) as
begin
open p_result for
select t.column1,
t.column2
from MY_TABLE t
where t.column3 is not null;
end;
Next you can iterate thought this cursor from Java/.Net, etc.
Apart from Manushin's answer, If you strictly wants answer in your format, You may try below -
is
cursor sample_cur is --this can be your select statement
select name, other_column1, other_column2 as today from names;
begin
for rec in sample_cur loop
-- step by step for each record you return in your cursor
dbms_output.put_line(rec.name || rec.other_column1 || rec.other_column2);
end loop;
end;

Oracle DB: how to store function result into variable inside procedure

Good day. I have a function:
create function get_n(search tt.pp%type)
return number
is rc number;
begin
select count(*)
into rc
from tt
where tt.pp=search;
return (rc);
end;
/
and i can get result as
variable qwe number;
begin
select get_n('sample')
into :qwe
from dual;
end;
print qwe;
So, it's successfully works. But by parts: i can't exec line with print at execution of other (PLS-00103: Encountered the symbol "PRINT"...). And it's really strange.
I try to get result from function in anonymous block and print it:
declare
qwe number;
begin
select get_n('sample')
into :qwe
from dual;
dbms_output.put_line(qwe);
exception
when others
then dbms_output.put_line(sqlerrm);
end;
/
And it's not print anything. Why?
Problem is :. Following code should work:
declare
qwe number;
begin
select get_n('sample')
into qwe
from dual;
dbms_output.put_line(qwe);
exception
when others
then dbms_output.put_line(sqlerrm);
end;
/
: means variable that need to be binded not variable inside PL/SQL block.
And in case of first block you're missing / after PL/SQL block what causes compiler reads print as part of PL/SQL not SQLplus script:
variable qwe number;
begin
select get_n('sample')
into :qwe
from dual;
end;
/
print qwe;

How can a stored procedure be executed in Oracle with in and out parameters?

Here's my stored procedure:
CREATE OR REPLACE PROCEDURE STATS_SD
(
P_ID IN NUMBER,
PRC OUT SYS_REFCURSOR
)
IS
BEGIN
OPEN PRC FOR
SELECT
ID,
SESID
FROM RESPONSES
WHERE ID IN (P_ID)
END;
When I try to execute it using
EXEC EXAM_STATS_STUDENTS_SD('6901');
I get the following error:
PLS-00306: wrong number or types of arguments in call to 'STATS_SD'
Do you have any ideas why?
Here is an example using an OUT parameter that is a sys_refcursor. Note that I close the cursor in the pl/sql block that uses it (which is important!):
create or replace procedure get_data(o_cur OUT SYS_REFCURSOR) as
begin
OPEN o_cur FOR
select * from emp;
end;
And using the get_data procedure:
declare
l_cur sys_refcursor;
l_row emp%rowtype;
begin
get_data(l_cur);
LOOP
fetch l_cur
into l_row;
exit when l_cur%notfound;
-- do something with l_row here
END LOOP;
close l_cur;
end;
You are passing a wrong datatype to your procedure.
According to your declaration a NUMBER is expected:
P_ID IN NUMBER
However, you pass a VARCHAR2 in your exec command:
EXEC EXAM_STATS_STUDENTS_SD('6901');
Note the '' around the value.
Try calling this instead:
EXEC EXAM_STATS_STUDENTS_SD(6901);
Apart from that you are missing the second parameter completely.

expression of wrong type oracle error

I am trying to execute the below plsql program, but facing expression of wrong type. Could anyone let me know what might be the error?
CREATE OR REPLACE PROCEDURE CLN_TBL (CTRLM IN VARCHAR2, CTG IN VARCHAR,SBCT IN NUMBER, RTDT IN NUMBER )
AS
V_SQL VARCHAR(2000);
V_TABLE VARCHAR(30);
CURSOR TBL_CUR
IS
SELECT TGT_TABLE_NAME FROM ODS_USER.CLNP WHERE CONTROLM=CTRLM AND APPL_CTGY=CTG AND APPL_SUB_CTGY= SBCT;
L_TGT_TABLE_NAME TBL_CUR%ROWTYPE;
BEGIN
OPEN TBL_CUR;
LOOP
FETCH TBL_CUR INTO L_TGT_TABLE_NAME;
V_TABLE:= L_TGT_TABLE_NAME ;
EXIT WHEN TBL_CUR%NOTFOUND;
V_SQL:='DELETE FROM '||V_TABLE||' WHERE RPT_DT_ID'||'=:1';
EXECUTE IMMEDIATE V_SQL using RTDT;
END LOOP;
COMMIT;
CLOSE TBL_CUR;
END;
As Exhausted said you cant assign row variable to varchar so You should take TGT_TABLE_NAME from row variable, like below should work;
CREATE OR REPLACE PROCEDURE CLN_TBL (CTRLM IN VARCHAR2, CTG IN VARCHAR,SBCT IN NUMBER, RTDT IN NUMBER )
AS
V_SQL VARCHAR(2000);
V_TABLE VARCHAR(30);
CURSOR TBL_CUR
IS
SELECT TGT_TABLE_NAME FROM ODS_USER.CLNP WHERE CONTROLM=CTRLM AND APPL_CTGY=CTG AND APPL_SUB_CTGY= SBCT;
L_TGT_TABLE_NAME TBL_CUR%ROWTYPE;
BEGIN
OPEN TBL_CUR;
LOOP
FETCH TBL_CUR INTO L_TGT_TABLE_NAME;
V_TABLE:= L_TGT_TABLE_NAME.TGT_TABLE_NAME ;
EXIT WHEN TBL_CUR%NOTFOUND;
V_SQL:='DELETE FROM '||V_TABLE||' WHERE RPT_DT_ID'||'=:1';
EXECUTE IMMEDIATE V_SQL using RTDT;
END LOOP;
COMMIT;
CLOSE TBL_CUR;
END;

Oracle cursor in update procedure. Identifier must be declared

I'm writing stored procedure for inserting (updating) REAL_START_DATE in TEST_SENDING_BOX_TABLE but getting my cursor "identifier must be declared exception"
PROCEDURE IN_SENDBOX_WORK_REALSTART (id_work TEST_SENDING_BOX_WORK.ID_SENDING_BOX_WORK%TYPE, real_start TEST_SENDING_BOX_WORK.REAL_START_DATE%TYPE) IS
CURSOR cur_work (id_w number) is
SELECT * FROM TEST_SENDING_BOX_WORK
WHERE ID_SENDING_BOX_WORK=id_w
FOR UPDATE OF REAL_START_DATE;
rec_to_mod TEST_SENDING_BOX_WORK%ROWTYPE;
BEGIN
open cur_work(id_work);
fetch сur_work into rec_to_mod;//Error(83,10): PLS-00201: identifier 'СUR_WORK' must be declared
UPDATE TEST_SENDING_BOX_WORK //Error(87,3): PL/SQL: SQL Statement ignored
SET REAL_START_DATE=real_start
WHERE CURRENT OF cur_work;
close сur_work; //Error(87,10): PLS-00201: identifier 'СUR_WORK' must be declared
END IN_SENDBOX_WORK_REALSTART;
However this similar procedure works flawlessly.
PROCEDURE IN_or_UP_SENDBOX_DEMOUNTDATE(id_sendbox TEST_SENDING_BOX_HISTORY.ID_SENDING_BOX%TYPE, p_demount TEST_SENDING_BOX_HISTORY.DEMOUNT_DATE%TYPE) IS
cursor send_box (id_sendbox number) is
SELECT * FROM TEST_SENDING_BOX_HISTORY
WHERE ID_SENDING_BOX=id_sendbox
FOR UPDATE OF DEMOUNT_DATE;
rec_to_mod TEST_SENDING_BOX_HISTORY%ROWTYPE;
BEGIN
open send_box(id_sendbox);
fetch send_box into rec_to_mod;
UPDATE TEST_SENDING_BOX_HISTORY
SET DEMOUNT_DATE=p_demount
where CURRENT OF send_box;
close send_box;
END IN_or_UP_SENDBOX_DEMOUNTDATE;
package TEST_DB_MOD_PKG
create or replace PACKAGE TEST_DB_MOD_PKG is
PROCEDURE INSERT_OBJ (p_idobj TEST_OBJ.ID_OBJ%TYPE, p_idobjtype TEST_OBJ.OBJ_KIND%TYPE);
PROCEDURE INSERT_SENDBOX (p_idsendingbox TEST_SENDING_BOX.ID_SENDING_BOX%TYPE, p_idsendboxmodel TEST_SENDING_BOX.ID_SENDING_BOX_MODEL%TYPE,
p_dateofman TEST_SENDING_BOX.DATE_OF_MANUFACTURE%TYPE,p_serialnum TEST_SENDING_BOX.SERIAL_NUMBER%TYPE);
PROCEDURE INSERT_DEFECT(p_iddef TEST_DEFECTIVENESS.ID_DEFECTIVENESS%TYPE, p_idsendbox TEST_DEFECTIVENESS.ID_SENDING_BOX%TYPE,
p_defkind TEST_DEFECTIVENESS.DEFECTIVENESS_KIND%TYPE,p_com TEST_DEFECTIVENESS.COMMEN%TYPE,
p_start TEST_DEFECTIVENESS.START_DATE%TYPE, p_end TEST_DEFECTIVENESS.END_DATE%TYPE);
PROCEDURE INSERT_SENDBOX_HISTORY(p_idobj TEST_SENDING_BOX_HISTORY.ID_OBJECT%TYPE, p_idsendbox TEST_SENDING_BOX_HISTORY.ID_SENDING_BOX%TYPE,
p_mount TEST_SENDING_BOX_HISTORY.MOUNT_DATE%TYPE);
PROCEDURE INSERT_OBJ_ATTR_VAL(p_idobjattr TEST_OBJ_ATTRIBUTE_VALUE.ID_OBJ_ATTRIBUTE%TYPE, p_idobj TEST_OBJ_ATTRIBUTE_VALUE.ID_OBJ%TYPE,
p_val TEST_OBJ_ATTRIBUTE_VALUE.VAL%TYPE);
PROCEDURE INSERT_WORK_ATTR_VAL(p_idworkattr TEST_WORK_ATTRIBUTE_VALUE.ID_WORK_ATTRIBUTE%TYPE, p_idwork TEST_WORK_ATTRIBUTE_VALUE.ID_WORK%TYPE,
p_val TEST_WORK_ATTRIBUTE_VALUE.VAL%TYPE);
PROCEDURE INSERT_SENDBOX_WORK(p_idwork TEST_SENDING_BOX_WORK.ID_SENDING_BOX_WORK%TYPE, p_id TEST_SENDING_BOX_WORK.ID_SENDING_BOX%TYPE,
p_idworkkind TEST_SENDING_BOX_WORK.ID_WORK_KIND%TYPE,p_idworker TEST_SENDING_BOX_WORK.ID_WORKER%TYPE,
p_start TEST_SENDING_BOX_WORK.START_DATE%TYPE,p_end TEST_SENDING_BOX_WORK.END_DATE%TYPE);
PROCEDURE INSERT_OBJ_WORK(p_idwork TEST_OBJ_WORK.ID_OBJ_WORK%TYPE, p_id TEST_OBJ_WORK.ID_OBJ%TYPE,
p_idworkkind TEST_OBJ_WORK.ID_WORK_KIND%TYPE,p_idworker TEST_OBJ_WORK.ID_WORKER%TYPE,
p_start TEST_OBJ_WORK.START_DATE%TYPE,p_end TEST_OBJ_WORK.END_DATE%TYPE);
PROCEDURE IN_or_UP_SENDBOX_DEMOUNTDATE(id_sendbox TEST_SENDING_BOX_HISTORY.ID_SENDING_BOX%TYPE, p_demount TEST_SENDING_BOX_HISTORY.DEMOUNT_DATE%TYPE);
PROCEDURE IN_SENDBOX_WORK_REALSTART (id_work TEST_SENDING_BOX_WORK.ID_SENDING_BOX_WORK%TYPE, real_start TEST_SENDING_BOX_WORK.REAL_START_DATE%TYPE);
END;
PACKAGE BODY TEST_DB_MOD_PKG
create or replace PACKAGE BODY TEST_DB_MOD_PKG IS
PROCEDURE INSERT_OBJ (p_idobj TEST_OBJ.ID_OBJ%TYPE, p_idobjtype TEST_OBJ.OBJ_KIND%TYPE) IS
BEGIN
INSERT INTO TEST_OBJ("ID_OBJ", "OBJ_KIND") VALUES (p_idobj, p_idobjtype);
END INSERT_OBJ;
PROCEDURE INSERT_SENDBOX (p_idsendingbox TEST_SENDING_BOX.ID_SENDING_BOX%TYPE, p_idsendboxmodel TEST_SENDING_BOX.ID_SENDING_BOX_MODEL%TYPE,
p_dateofman TEST_SENDING_BOX.DATE_OF_MANUFACTURE%TYPE,p_serialnum TEST_SENDING_BOX.SERIAL_NUMBER%TYPE) IS
BEGIN
INSERT INTO TEST_SENDING_BOX (ID_SENDING_BOX, ID_SENDING_BOX_MODEL,DATE_OF_MANUFACTURE,SERIAL_NUMBER)
VALUES (p_idsendingbox , p_idsendboxmodel, p_dateofman, p_serialnum);
END INSERT_SENDBOX ;
PROCEDURE INSERT_DEFECT(p_iddef TEST_DEFECTIVENESS.ID_DEFECTIVENESS%TYPE, p_idsendbox TEST_DEFECTIVENESS.ID_SENDING_BOX%TYPE,
p_defkind TEST_DEFECTIVENESS.DEFECTIVENESS_KIND%TYPE,p_com TEST_DEFECTIVENESS.COMMEN%TYPE,
p_start TEST_DEFECTIVENESS.START_DATE%TYPE, p_end TEST_DEFECTIVENESS.END_DATE%TYPE) IS
BEGIN
INSERT INTO TEST_DEFECTIVENESS (ID_DEFECTIVENESS, ID_SENDING_BOX,DEFECTIVENESS_KIND,COMMEN,START_DATE,END_DATE)
VALUES (p_iddef , p_idsendbox, p_defkind, p_com,p_start,p_end);
END INSERT_DEFECT ;
PROCEDURE INSERT_SENDBOX_HISTORY(p_idobj TEST_SENDING_BOX_HISTORY.ID_OBJECT%TYPE, p_idsendbox TEST_SENDING_BOX_HISTORY.ID_SENDING_BOX%TYPE,
p_mount TEST_SENDING_BOX_HISTORY.MOUNT_DATE%TYPE) IS
BEGIN
INSERT INTO TEST_SENDING_BOX_HISTORY (ID_OBJECT,ID_SENDING_BOX,MOUNT_DATE)
VALUES (p_idobj, p_idsendbox,p_mount);
END INSERT_SENDBOX_HISTORY ;
PROCEDURE INSERT_OBJ_ATTR_VAL(p_idobjattr TEST_OBJ_ATTRIBUTE_VALUE.ID_OBJ_ATTRIBUTE%TYPE, p_idobj TEST_OBJ_ATTRIBUTE_VALUE.ID_OBJ%TYPE,
p_val TEST_OBJ_ATTRIBUTE_VALUE.VAL%TYPE) IS
BEGIN
INSERT INTO TEST_OBJ_ATTRIBUTE_VALUE (ID_OBJ_ATTRIBUTE,ID_OBJ,VAL)
VALUES (p_idobjattr , p_idobj,p_val);
END INSERT_OBJ_ATTR_VAL ;
PROCEDURE INSERT_WORK_ATTR_VAL(p_idworkattr TEST_WORK_ATTRIBUTE_VALUE.ID_WORK_ATTRIBUTE%TYPE, p_idwork TEST_WORK_ATTRIBUTE_VALUE.ID_WORK%TYPE,
p_val TEST_WORK_ATTRIBUTE_VALUE.VAL%TYPE) IS
BEGIN
INSERT INTO TEST_WORK_ATTRIBUTE_VALUE(ID_WORK_ATTRIBUTE,ID_WORK,VAL)
VALUES (p_idworkattr , p_idwork,p_val);
END INSERT_WORK_ATTR_VAL ;
PROCEDURE INSERT_SENDBOX_WORK(p_idwork TEST_SENDING_BOX_WORK.ID_SENDING_BOX_WORK%TYPE, p_id TEST_SENDING_BOX_WORK.ID_SENDING_BOX%TYPE,
p_idworkkind TEST_SENDING_BOX_WORK.ID_WORK_KIND%TYPE,p_idworker TEST_SENDING_BOX_WORK.ID_WORKER%TYPE,
p_start TEST_SENDING_BOX_WORK.START_DATE%TYPE,p_end TEST_SENDING_BOX_WORK.END_DATE%TYPE) IS
BEGIN
INSERT INTO TEST_SENDING_BOX_WORK(ID_SENDING_BOX_WORK,ID_SENDING_BOX,ID_WORK_KIND,ID_WORKER,START_DATE,END_DATE)
VALUES (p_idwork , p_id,p_idworkkind,p_idworker,p_start,p_end );
END INSERT_SENDBOX_WORK;
PROCEDURE INSERT_OBJ_WORK(p_idwork TEST_OBJ_WORK.ID_OBJ_WORK%TYPE, p_id TEST_OBJ_WORK.ID_OBJ%TYPE,
p_idworkkind TEST_OBJ_WORK.ID_WORK_KIND%TYPE,p_idworker TEST_OBJ_WORK.ID_WORKER%TYPE,
p_start TEST_OBJ_WORK.START_DATE%TYPE,p_end TEST_OBJ_WORK.END_DATE%TYPE) IS
BEGIN
INSERT INTO TEST_OBJ_WORK(ID_OBJ_WORK,ID_OBJ,ID_WORK_KIND,ID_WORKER,START_DATE,END_DATE)
VALUES (p_idwork , p_id,p_idworkkind,p_idworker,p_start,p_end );
END INSERT_OBJ_WORK;
PROCEDURE IN_or_UP_SENDBOX_DEMOUNTDATE(id_sendbox TEST_SENDING_BOX_HISTORY.ID_SENDING_BOX%TYPE, p_demount TEST_SENDING_BOX_HISTORY.DEMOUNT_DATE%TYPE) IS
cursor send_box (id_sendbox number) is
SELECT * FROM TEST_SENDING_BOX_HISTORY
WHERE ID_SENDING_BOX=id_sendbox
FOR UPDATE OF DEMOUNT_DATE;
rec_to_mod TEST_SENDING_BOX_HISTORY%ROWTYPE;
BEGIN
open send_box(id_sendbox);
fetch send_box into rec_to_mod;
UPDATE TEST_SENDING_BOX_HISTORY
SET DEMOUNT_DATE=p_demount
where CURRENT OF send_box;
close send_box;
END IN_or_UP_SENDBOX_DEMOUNTDATE;
PROCEDURE IN_SENDBOX_WORK_REALSTART (id_work TEST_SENDING_BOX_WORK.ID_SENDING_BOX_WORK%TYPE, real_start TEST_SENDING_BOX_WORK.REAL_START_DATE%TYPE) IS
cursor cur_work (id_work number) is
SELECT * FROM TEST_SENDING_BOX_WORK
WHERE ID_SENDING_BOX_WORK=id_work
FOR UPDATE OF REAL_START_DATE;
rec_to_mod TEST_SENDING_BOX_WORK%ROWTYPE;
BEGIN
open cur_work(id_work);
fetch сur_work into rec_to_mod;
UPDATE TEST_SENDING_BOX_WORK
SET REAL_START_DATE=real_start
WHERE CURRENT OF cur_work;
close сur_work;
END IN_SENDBOX_WORK_REALSTART;
END TEST_DB_MOD_PKG;
link to screenshot
The error is actually correct, but it's rather subtle. The names are not the same. The declaration, open and current of have one name; the fetch and close have something very slightly different. You can see that if you do a find in your browser and search for cur_work, particularly if it does highlighting; with your full code there are 6 matches instead of 10.
So, what's the difference? Here's a dump of the five references:
select dump('cursor cur_work') from dual;
select dump('open cur_work') from dual;
select dump('fetch сur_work') from dual;
select dump('OF cur_work') from dual;
select dump('close сur_work') from dual;
... adjusted so the space before the variable names is aligned.
Typ=96 Len=15: 99,117,114,115,111,114,32,99,117,114,95,119,111,114,107
Typ=96 Len=13: 111,112,101,110,32,99,117,114,95,119,111,114,107
Typ=96 Len=15: 102,101,116,99,104,32,209,129,117,114,95,119,111,114,107
Typ=96 Len=11: 79,70,32,99,117,114,95,119,111,114,107
Typ=96 Len=15: 99,108,111,115,101,32,209,129,117,114,95,119,111,114,107
The character immediately after the space is 99 for three of them, and 209,129 for the other two. The 99 is actually c as you'd expected. The other is, according to this, U+0441, 'Cyrillic small letter es', which renders as с. So you're mixing Latin and Cyrillic characters that just happen to look the same.
Retype the variable name in the fetch and close statements and it'll compile OK. (But preferably not in the system schema...)

Resources