Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use a collection within an Oracle SQL statement

I want to write an Oracle function that collects some data in multiple steps into a collection variable and use that collection data within a SELECT query like in this very simplified example:

CREATE OR REPLACE FUNCTION TESTFUNC01 RETURN VARCHAR2 AS 
  -- INT_LIST is declared globally as "TYPE INT_LIST IS TABLE OF INTEGER"
  MyList INT_LIST := INT_LIST();
  MyName VARCHAR2(512);
BEGIN
  MyList.Extend(3);
  MyList(0) := 1;
  MyList(1) := 2;
  MyList(2) := 3;

  SELECT Name INTO MyName
  FROM Item WHERE ItemId NOT IN MyList;
  RETURN MyName;
END TESTFUNC01;

Unfortunately the part "NOT IN MyList" is no valid SQL. Is there a way to achieve this?

like image 471
blerontin Avatar asked Sep 27 '11 13:09

blerontin


People also ask

Can an Oracle function return a collection?

Yes it can be done, you need to create a TYPE and then return that TYPE in your function, see very simplistic example below, once you have a database level TYPE you can re-use it: SQL> create or replace type t_varchar2 is table of varchar2(4000) 5 / Type created.

Can I use group by in Oracle?

In Oracle GROUP BY clause is used with SELECT statement to collect data from multiple records and group the results by one or more columns.

What is the use of collection in Oracle?

Using PL/SQL Collections with SQL Statements. Collections let you manipulate complex datatypes within PL/SQL. Your program can compute subscripts to process specific elements in memory, and use SQL to store the results in database tables.

How do you collect in SQL?

COLLECT is an aggregate that returns a table. It is usually used with GROUP BY. COLLECT gathers up the specified fields and their values from within each subgroup formed by GROUP BY, so those fields can be used in an arbitrary SQL expression or together with some other aggregate function.


2 Answers

What you're looking for is the table function:

CREATE OR REPLACE FUNCTION TESTFUNC01 RETURN VARCHAR2 AS 
  -- INT_LIST is declared globally as "TYPE INT_LIST IS TABLE OF INTEGER"
  MyList INT_LIST := INT_LIST();
  MyName VARCHAR2(512);
BEGIN
  MyList.Extend(3);
  MyList(1) := 1;
  MyList(2) := 2;
  MyList(3) := 3;

  SELECT Name INTO MyName
  FROM Item WHERE ItemId NOT IN (select * from table(MyList));
  RETURN MyName;
END TESTFUNC01;
like image 125
Allan Avatar answered Oct 19 '22 06:10

Allan


You can do it like this:

CREATE OR REPLACE FUNCTION TESTFUNC01 RETURN VARCHAR2 AS 
  -- INT_LIST is declared globally as "TYPE INT_LIST IS TABLE OF INTEGER"
  MyList INT_LIST := INT_LIST();
  MyName VARCHAR2(512);
BEGIN
  MyList.Extend(3);
  MyList(1) := 1;
  MyList(2) := 2;
  MyList(3) := 3;

  SELECT Name INTO MyName
  FROM Item WHERE ItemId NOT IN (SELECT COLUMN_VALUE FROM TABLE(MyList));
  RETURN MyName;
END TESTFUNC01;

Note that I've also changed the list indices. The start with 1 (not 0).

like image 27
Codo Avatar answered Oct 19 '22 06:10

Codo