Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a table variable be used in a select statement where clause?

I have a stored procedure that is doing a two-step query. The first step is to gather a list of VARCHAR2 type characters from a table and collect them into a table variable, defined like this:

TYPE t_cids IS TABLE OF VARCHAR2(50) INDEX BY PLS_INTEGER;
v_cids t_cids;

So basically I have:

SELECT item BULK COLLECT INTO v_cids FROM table_one;

This works fine up until the next bit.

Now I want to use that collection in the where clause of another query within the same procedure, like so:

SELECT * FROM table_two WHERE cid IN v_cids;

Is there a way to do this? I am able to select an individual element, but I would like to use the table variable like a would use a regular table. I've tried variations using nested selects, but that doesn't seem to work either.

Thanks a lot,

Zach

like image 827
zmouser Avatar asked Dec 01 '11 20:12

zmouser


People also ask

Which operator Cannot be used in WHERE clause?

Join, subquery and aggregate functions are not supported.

Can you DECLARE a variable in a SELECT statement?

Variables in SQL procedures are defined by using the DECLARE statement. Values can be assigned to variables using the SET statement or the SELECT INTO statement or as a default value when the variable is declared.

Can you SELECT into a table variable?

The question was it is possible to do SELECT INTO a Table Variable in T-SQL? The answer is it is not possible at all. Let us understand what we can do in a similar situation.

Can you use a variable in the WHERE clause SQL?

The variable may be used in subsequent queries wherever an expression is allowed, such as in a WHERE clause or in an INSERT statement. A common situation in which SQL variables come in handy is when you need to issue successive queries on multiple tables that are related by a common key value.


1 Answers

You have several choices as to how you achieve this.

If you want to use a collection, then you can use the TABLE function to select from it but the type of collection you use becomes important.

for a brief example, this creates a database type that is a table of numbers:

CREATE TYPE number_tab AS TABLE OF NUMBER
/

Type created.

The next block then populates the collection and performs a rudimentary select from it using it as a table and joining it to the EMP table (with some output so you can see what's happening):

DECLARE
   -- Create a variable and initialise it
   v_num_tab number_tab := number_tab();
   --
   -- This is a collection for showing the output
   TYPE v_emp_tabtype IS TABLE OF emp%ROWTYPE
        INDEX BY PLS_INTEGER;
   v_emp_tab v_emp_tabtype;
BEGIN
   -- Populate the number_tab collection
   v_num_tab.extend(2);
   v_num_tab(1) := 7788;
   v_num_tab(2) := 7902;
   --
   -- Show output to prove it is populated
   FOR i IN 1 .. v_num_tab.COUNT
   LOOP
      dbms_output.put_line(v_num_tab(i));
   END LOOP;
   --
   -- Perform a select using the collection as a table
   SELECT e.*
     BULK COLLECT INTO v_emp_tab
     FROM emp e
    INNER JOIN TABLE(v_num_tab) nt
       ON (e.empno = nt.column_value);
   --
   -- Display the select output
   FOR i IN 1 .. v_emp_tab.COUNT
   LOOP
      dbms_output.put_line(v_emp_tab(i).empno||' is a '||v_emp_tab(i).job);
   END LOOP;
END;

You can see from this that the database TYPE collection (number_tab) was treated as a table and could be used as such.

Another option would be to simply join your two tables you are selecting from in your example:

SELECT tt.*
  FROM table_two tt
 INNER JOIN table_one to
    ON (to.item = tt.cid);

There are other ways of doing this but the first might suit your needs best.

Hope this helps.

like image 196
Ollie Avatar answered Sep 28 '22 02:09

Ollie