Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BULK COLLECT into a table of objects

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.

like image 469
xacinay Avatar asked May 17 '13 13:05

xacinay


People also ask

Which type of collection is used while creating bulk collect?

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.

What does bulk collect into do?

A SELECT INTO statement with the optional BULK COLLECT keywords preceding the INTO keyword retrieves multiple rows into an array.

Why bulk collect is faster in Oracle?

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.

What is difference between bulk collect and bulk bind in Oracle?

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.


1 Answers

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 ) ;
like image 134
Alex Poole Avatar answered Sep 25 '22 12:09

Alex Poole