Reputation: 1
I am trying to use a cursor here, I would like to know how to i access the cursor field in the select column?
I have an implementation as below,
create or replace TYPE "TABLE_TYPE_SAMPLE" AS OBJECT(
ENTITY_NAME VARCHAR2(100)
);
create or replace TYPE "TABLE_SAMPLE" AS TABLE OF TABLE_TYPE_SAMPLE;
CREATE OR REPLACE FUNCTION segmentFields(
txnId VARCHAR2)
RETURN TABLE_SAMPLE
IS
attValue VARCHAR2(20);
curStr VARCHAR2(20);
flexTable TABLE_SAMPLE := TABLE_TYPE_SAMPLE();
CURSOR cur_seg
IS
(SELECT colA
FROM table1 -- (table name has column colA)
WHERE id = txnId
);
BEGIN
FOR cur_recd IN cur_seg
LOOP
curStr := cur_recd.colA;
SELECT curStr into attValue FROM PER_PEOPLE_GROUPS;
flexTable.EXTEND;
flexTable(flexTable.count) := (TABLE_TYPE_SAMPLE(attValue)) ;
END LOOP;
RETURN flexTable;
END;
The function complied without errors. but when I try to run below query
select * from table(segmentFields(480));
I get the below error,
ORA-01422: exact fetch returns more than requested number of rows
ORA-06512: at "SEGMENTFIELDS", line 19
01422. 00000 - "exact fetch returns more than requested number of rows"
*Cause: The number specified in exact fetch is less than the rows returned.
*Action: Rewrite the query or change number of rows requested
I want to understand, what is wrong with this implementation.
Thank you.
Upvotes: 0
Views: 312
Reputation: 66
error in row:
SELECT curStr into attValue FROM PER_PEOPLE_GROUPS;
that executes the code? how many rows in PER_PEOPLE_GROUPS
?
error indicates that more than one
. You may need to put a condition in where clause?
Upvotes: 0
Reputation: 146329
This query has no WHERE clause:
SELECT curStr into attValue FROM PER_PEOPLE_GROUPS;
That means it will return hits for all the rows in PER_PEOPLE_GROUPS. The SELECT ... INTO construct populates a single variable and so requires a query which returns exactly one row. The ORA-01422 message indicates that you're not executing an exact fetch, obviously because PER_PEOPLE_GROUPS has more than one row.
Several possible solutions, depending on what you're trying to achieve:
flexTable(flexTable.count) := (TABLE_TYPE_SAMPLE(cur_recd.colA))
On the face of it, discarding the SELECT seems the best option as it doesn't provide you with any information. However, it also seems likely that you are trying to implement some other business logic which isn't expressed in the posted code, so probably you need to make several changes.
Upvotes: 0
Reputation: 10551
The problem is with the select into. Not sure why that's there in the first place. The value from your cursor is available in cur_recd.cola and you can use it directly.
create or replace function segmentfields(txnid varchar2) return table_sample is
flextable table_sample := table_type_sample();
cursor cur_seg is(
select cola
from table1 -- (table name has column colA)
where id = txnid);
begin
for cur_recd in cur_seg
loop
flextable.extend;
flextable(flextable.count) := (table_type_sample(cur_recd.cola));
end loop;
return flextable;
end;
Upvotes: 0