Home>Question Details



sunil -- Thanks for the question regarding "Unable to store dynamic select into cursor", version 9.0.5

Submitted on 9-Jan-2008 11:09 Central time zone
Last updated 10-Jan-2008 17:59

You Asked

Dear Tom,
I am writing a SP which is using two table as

CREATE TABLE TEST2
(
AGE NUMBER,
NAME VARCHAR2(60 BYTE),
EMPID VARCHAR2(60 BYTE)
)

INSERT INTO test2 VALUES (25,'sunil','7940');



CREATE TABLE INPUT_PARAM
(
COLUMNNAME VARCHAR2(100 BYTE)
)

INSERT INTO input_param VALUES ('AGE');


--------------------------------------------------------------

Stored Procedure
--------------------------------------------------------------


CREATE OR REPLACE PROCEDURE Cal_Score_Test_tom

IS




selectstr VARCHAR2(4000);
LENGTH NUMBER ;
selectstrChanged VARCHAR2(4000);
vTable VARCHAR2(30) := 'input_param';
vCursor sys_refcursor;

CURSOR C2 IS
SELECT COLUMNNAME cname FROM input_param;

TYPE tDept IS TABLE OF input_param%ROWTYPE;
vDept tDept;

BEGIN

--selectstr:='Select ';
FOR J IN c2 LOOP
IF c2%ROWCOUNT != 0 THEN

selectstr:=selectstr||J.cname||',' ;
ELSE
selectstr:=selectstr||J.cname ;
END IF;
END LOOP;

SELECT LENGTH(selectstr) INTO LENGTH FROM dual;
selectstrChanged:=SUBSTR(selectstr,0, (LENGTH-1));
selectstrChanged:=selectstrChanged|| ' FROM test2 ';


OPEN vCursor FOR ('select ' || selectstrChanged);
FETCH vCursor BULK COLLECT INTO vDept;
CLOSE vCursor;

IF vDept.COUNT > 0
THEN
DBMS_OUTPUT.PUT_LINE('Elements in ---> ' || TO_CHAR(vDept.COUNT));

FOR n IN vDept.FIRST..vDept.LAST
LOOP
DBMS_OUTPUT.PUT_LINE('Elements in --->test1 ');

END LOOP;

END IF;

END;
/

---------------------------------------------------------------
-------------------------------------------------------------
and after excution i get the following output

SQL> set serveroutput on
SQL> BEGIN
2 FINLOS_PHP.CAL_SCORE_TEST_TOM;
3 COMMIT;
4 END;
5 /
Elements in ---> 1
Elements in --->test1


which is wrong .I am unable to retrieve all the values from the cursor.
IS there anyway to do so ??
Please help.

Regards
Sunil


Dear Tom,

I am trying to make a select query which will selecting the the column on the basis of the values present in the table for example.
If i am putting age in input_param table then my select statement will be

select age from test2;

now suppose after some time i need to select two parameters like age,empid like

select age,empid from test2;

then i will be able to do by putting just one entry into input_param (empid).

Utimately i want to some manipulations on the values returned by my final select ...in this case ..

select age,empid from test2;

As for i know the the best way will be if i can get this select into a cursor ...but i am unable to since i dont know datatype of the variable variable vDept and most probably this is causing wrong output

FETCH vCursor BULK COLLECT INTO vDept;


Hope this clearifies my requiremet and

thanks for your useful suggestions ....






and we said...

You cannot process a variable select list like that in PLSQL using a refcursor.

You can only use DBMS_SQL. It provides a procedural API to

a) describe a result set, detailing the number and datatypes of the retrieved columns
b) procedures to access the I'th column of a result set

That said, I will advise you to ABANDON this approach. Use STATIC SQL, don't be afraid to have 4 or 5 procedures - instead of one "super generic one"

If you are using dynamic sql at the drop of a hat - you are doing it wrong. dynamic SQL should be the path of LAST RESORT - when no other way works.

if you persist down this path, search this site for dbms_sql, hundreds of examples.
-------------------------------------------------------------------------------


I cannot being to say how bad it would be to have a variable (eg: LENGTH) named after a function (eg: LENGTH). Get into the habit of prefixing local variables with L_ and parameters with P_ and globals in packages with G_

... SELECT LENGTH(selectstr) INTO LENGTH FROM dual;...

why do that when:

l_length := length(selectstr);

would do it more efficiently? PLSQL is a programming language, this is not TSQL :)


why is your output wrong? there is, well, 1 row in test2 - and it is saying "I found one row, thanks" and then saying 'I am positioned at the first array element, but I decided to not print it out'

I'm at a complete loss as to what you are trying to do...

so maybe instead of posting code that doesn't work - you tell us what you are trying to do.
Reviews    
5 stars   January 10, 2008 - 11pm Central time zone
Reviewer: sunil vishwakarma 
Thanks for giving a clear approach ...





All information and materials provided here are provided "as-is"; Oracle disclaims all express and implied warranties, including, the implied warranties of merchantability or fitness for a particular use. Oracle shall not be liable for any damages, including, direct, indirect, incidental, special or consequential damages for loss of profits, revenue, data or data use, incurred by you or any third party in connection with the use of this information or these materials.

About Oracle | Legal Notices and Terms of Use | Privacy Statement