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?
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.
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.
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.
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.
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;
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).
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