When attempting to use a BULK COLLECT
statement I got error ORA-00947: not enough values
.
An example script:
CREATE OR REPLACE
TYPE company_t AS OBJECT (
Company VARCHAR2(30),
ClientCnt INTEGER );
/
CREATE OR REPLACE
TYPE company_set AS TABLE OF company_t;
/
CREATE OR REPLACE
FUNCTION piped_set (
v_DateBegin IN DATE,
v_DateEnd IN DATE
)
return NUMBER /*company_set pipelined*/ as
v_buf company_t := company_t( NULL, NULL);
atReport company_set;
sql_stmt VARCHAR2(500) := '';
begin
select * BULK COLLECT INTO atReport
from (
SELECT 'Descr1', 1 from dual
UNION
SELECT 'Descr2', 2 from dual ) ;
return 1;
end;
The error occurs at the line select * BULK COLLECT INTO atReport
.
Straight PL/SQL works fine by the way (so no need to mention it as a solution). Usage of BULK COLLECT
into a user table type is the question.
About BULK COLLECT It can be used with all three types of collections: associative arrays, nested tables, and varrays. You can fetch into individual collections (one for each expression in the SELECT list) or a single collection of records.
A SELECT INTO statement with the optional BULK COLLECT keywords preceding the INTO keyword retrieves multiple rows into an array.
Since the BULK COLLECT fetches the record in BULK, the INTO clause should always contain a collection type variable. The main advantage of using BULK COLLECT is it increases the performance by reducing the interaction between database and PL/SQL engine.
Bulk binds can improve the performance when loading collections from a queries. The BULK COLLECT INTO construct binds the output of the query to the collection.
Your company_set
is a table of objects, and you're selecting values, not objects comprised of those values. This will compile:
select * BULK COLLECT INTO atReport
from (
SELECT company_t('Descr1', 1) from dual
UNION
SELECT company_t('Descr2', 2) from dual ) ;
... but when run will throw ORA-22950: cannot ORDER objects without MAP or ORDER method
because the union
does implicit ordering to identify and remove duplicates, so use union all
instead:
select * BULK COLLECT INTO atReport
from (
SELECT company_t('Descr1', 1) from dual
UNION ALL
SELECT company_t('Descr2', 2) from dual ) ;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With