Home
AskTheOracle Blog
Oracle Tips & Tricks
Oracle Training
Oracle Tutorials
PL/SQL
SQL
Advanced Tutorials
Performance Tuning
Certification
Oracle 10g
Oracle 11g
Oracle and .Net
Oracle Utilities
Developer Tools
Oracle Questions?
Oracle News
Search This Site
About Us
Disclaimer
Privacy Policy
Contact Us
Subscribe To This Site
XML RSS
Add to Google
Add to My Yahoo!
Add to My MSN
Subscribe with Bloglines

How to convert local PL/SQL table to table I can select from

by Austen
(D.C.)

Question:

I am trying to figure out how I can convert an Oracle PL/SQL local table (of numbers) to a table that I can select from.

I want to pass this table into a cursor, and use it in the where clause, similar to this:


CURSOR my_csr
(in_table IN number_table)
IS
BEGIN
SELECT *
FROM table_x tx
WHERE tx.id_num IN (SELECT * FROM in_table)
END;


Currently, I have my program set up to loop through this local collection, and fetch the cursor with 1 number at a time. But I need it to take in the entire table of numbers, instead of just one. So that I can return all of my results at once.

Is there a way I can convert my local table type into a table that I can select from and use in queries?

Thanks!


Answer:

The short answer is "YES", you'll be pleased to hear. However the table type must be must be an attribute data type - in other words the type must be declared at the schema level rather than locally - which restricts this to VARRAY table types and NESTED TABLE types (i.e. you can't use Oracle PL/SQL associative arrays).

Let's look at an example. First of all we'll define the table type outside of our PL/SQL block:

create or replace type num_tab is table of number;

Next we'll declare an anonymous PL/SQL block to create and populate a local PL/SQL table of the type just created, declare a cursor to select from this table and then display the output.

We're going to cheat in this example and hard code the entries in the local table but we could populate the table from the Oracle database (by using BULK COLLECT for example). Here is our Pl/SQL code:


DECLARE

  local_table num_tab;

  CURSOR my_csr (in_table IN num_tab)
  IS
  SELECT *
  FROM employees
  WHERE department_id IN
    (SELECT column_value
    FROM TABLE(CAST (in_table AS num_tab))
    );

begin

  local_table := num_tab(10,20,30);
          -- populate PL/SQL table

  for emp in my_csr(local_table) loop
          -- run a cursor over it

     dbms_output.put_line('emp id = '||emp.employee_id);

  end loop;

end;

When we run this against the sample HR schema in the Oracle database it produces the following results:

emp id = 200
emp id = 202
emp id = 201
emp id = 119
emp id = 118
emp id = 117
emp id = 116
emp id = 115
emp id = 114

The important operation in the PL/SQL code is the CAST function combined with TABLE to create a table collection expression. This enables us to use the table in a SQL query as if it were a normal table stored in the Oracle database.

This example used a NESTED TABLE type, we could just as easily use a VARRAY. All we would need to do is change the type definition as follows:

create or replace type num_tab is varray(4) of number;

Obviously this puts a limit on the size of the table (in this case 4) which may not be what you want.

We could also populate the PL/SQL from the database by using the BULK COLLECT statement (instead of initializing the table with constant values) like this:

SELECT department_id BULK COLLECT INTO local_table FROM departments;


For more help with Oracle PL/SQL, see our series of tutorials starting at http://www.asktheoracle.net/plsql-tutorial.html or why not enquire about our classroom-quality online Oracle training or our instructor-led training in the US and the UK?

Click here to post comments.

Join in and write your own page! It's easy to do. How?
Simply click here to return to Oracle Questions
.