Oracle cursor in update procedure. Identifier must be declared - oracle

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...)

Related

ORA-01001: invalid cursor . Passing cursor to a procedure

When I execute the code below I got ORA-01001: invalid cursor and ORA-06512 error. It was not always the case.I thought I pass the cursor to MY_READ procedure by reference and can close it there. But as I started to get the error above suddenly I concluded, that maybe I'm not passing a reference but the copy of the cursor. Am I right? Is it possible to read close the cursor in MY_READ function?
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
PROCEDURE REP_HELPER1 (myIdx IN BINARY_INTEGER, from_d IN DATE, rep_table IN OUT rep_table_T) IS
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
myCUR1 SYS_REFCURSOR;
BEGIN
OPEN myCUR1 FOR SELECT myField1,
myField2,
myField3,
myField4,
myField5,
myField6,
myField7,
myField8,
myField9,
myField10,
myField11,
myField12,
myField13,
myField14,
myField15,
myField16,
myField17,
myField18,
myField19,
myField20,
myField21,
myField22,
myField23,
myField24,
myField25,
myField26,
myField27,
myField28,
myField29,
myField30,
myField31
FROM myTable;
MY_READ(myIdx , myCUR1, rep_table)
END REP_HELPER1;
--Am I passing here a copy of a cursor and not a reference?
PROCEDURE MY_READ(myIdx IN BINARY_INTEGER, cur IN SYS_REFCURSOR, rep_table IN OUT rep_table_T) IS
BEGIN
FETCH cur INTO rep_table(myIdx).day1, rep_table(myIdx).day2, rep_table(myIdx).day3, rep_table(myIdx).day4, rep_table(myIdx).day5,
rep_table(myIdx).day6, rep_table(myIdx).day7, rep_table(myIdx).day8, rep_table(myIdx).day9, rep_table(myIdx).day10,
rep_table(myIdx).day11, rep_table(myIdx).day12, rep_table(myIdx).day13, rep_table(myIdx).day14, rep_table(myIdx).day15,
rep_table(myIdx).day16, rep_table(myIdx).day17, rep_table(myIdx).day18, rep_table(myIdx).day19, rep_table(myIdx).day20,
rep_table(myIdx).day21, rep_table(myIdx).day22, rep_table(myIdx).day23, rep_table(myIdx).day24, rep_table(myIdx).day25,
rep_table(myIdx).day26, rep_table(myIdx).day27, rep_table(myIdx).day28, rep_table(myIdx).day29, rep_table(myIdx).day30,
rep_table(myIdx).day31;
IF cur%NOTFOUND THEN -- here comes ORA-06512 in a stack
dbms_output.put_line('ERROR' || nIndex);
END IF;
CLOSE cur;
END MY_READ;
When I do FETCH and close in REP_HELPER1 I'm not getting the error.
This simple example seems equivalent to yours and works fine:
declare
mycur sys_refcursor;
procedure my_read (cur sys_refcursor) is
job long;
sal number;
begin
fetch cur into job, sal;
dbms_output.put_Line(job||' '||sal);
close cur;
end;
begin
open mycur for select job, sal from emp where ename = 'KING';
my_read (mycur);
end;
So I don't think that is the issue.
According to https://www.techonthenet.com/oracle/errors/ora01001.php:
You tried to reference a cursor that does not yet exist. This may have
happened because:
You've executed a FETCH cursor before OPENING the cursor.
You've executed a CLOSE cursor before OPENING the cursor.
You've executed a FETCH cursor after CLOSING the cursor.

Oracle 11g - Add query results to SYS_REFCURSOR in a LOOP

Currently, I'm working on creating a stored procedure that I can pass a list of strings to from my C# application using a DataReader. So part of it is also properly declaring that Associative Array so the stored procedure can accept the data.
Here is what I currently have (I'm not too concerned about the C# side of things at the moment):
CREATE OR REPLACE PACKAGE TEST_PACKAGE_01
AS
TYPE t_string_list is table of VARCHAR2(4000) index by pls_integer;
PROCEDURE SP_TEST_01(in_list IN t_string_list, out_cursor OUT SYS_REFCURSOR);
END TEST_PACKAGE_01;
/
CREATE OR REPLACE PACKAGE BODY TEST_PACKAGE_01
AS
PROCEDURE SP_TEST_01(in_list IN t_string_list, out_cursor OUT SYS_REFCURSOR)
IS
BEGIN
OPEN out_cursor;
FORALL indx IN 1..in_list.COUNT
-- I have tried numerous different things here with no success, this is just what I have in my latest iteration
INSERT INTO out_cursor Values (SELECT * FROM SOME_TABLE WHERE SOME_COLUMN = in_list(indx));
CLOSE out_cursor;
END SP_TEST_01;
END TEST_PACKAGE_01;
Within the body of the procedure, I managed to get it to return a SYS_REFCURSOR just fine, albeit just a test without any input. Something kind of like:
OPEN out_cursor FOR
SELECT * FROM SOME_TABLE;
I can't use a simple IN statement for the query against SOME_TABLE since in_list can potentially contain thousands of records. Ideally, I'd like to populate out_cursor with one statement, instead of performing a loop.
Cursors are pretty new territory for me, so maybe it isn't possible to do what I'm thinking with them, but I haven't seen anything to the contrary.
In 11g you can't access the PL/SQL table type from SQL, even if that SQL is within a PL/SQL block. You can create a schema-level type instead:
CREATE OR REPLACE TYPE t_string_list AS TABLE OF VARCHAR2(4000)
/
Then your package becomes:
CREATE OR REPLACE PACKAGE TEST_PACKAGE_01
AS
PROCEDURE SP_TEST_01(in_list IN t_string_list, out_cursor OUT SYS_REFCURSOR);
END TEST_PACKAGE_01;
/
CREATE OR REPLACE PACKAGE BODY TEST_PACKAGE_01
AS
PROCEDURE SP_TEST_01(in_list IN t_string_list, out_cursor OUT SYS_REFCURSOR)
IS
BEGIN
OPEN out_cursor FOR
SELECT *
FROM SOME_TABLE
WHERE SOME_COLUMN IN (
SELECT * FROM TABLE(in_list)
);
END SP_TEST_01;
END TEST_PACKAGE_01;
/
or with a join instead of IN:
CREATE OR REPLACE PACKAGE BODY TEST_PACKAGE_01
AS
PROCEDURE SP_TEST_01(in_list IN t_string_list, out_cursor OUT SYS_REFCURSOR)
IS
BEGIN
OPEN out_cursor FOR
SELECT st.*
FROM TABLE(in_list) t
JOIN SOME_TABLE st ON st.SOME_COLUMN = t.COLUMN_VALUE;
END SP_TEST_01;
END TEST_PACKAGE_01;
/
The TABLE() is a table collection expression.
db<>fiddle with made-up table and anonymous block to test.

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;

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

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;
/

Resources