3

I will give You two slices of code from the SQL script I'm currently working with, but they will suffice. Firstly, I am declaring a variable:

FUNCTION Run
( i_PlafId  IN INTEGER
)
RETURN INTEGER
IS

l_tables_excl VARCHAR2(256) := 'TABLE_1,TABLE_2';

Later I would like to use it in some place, like this:

AND cos.table_name NOT IN l_tables_excl

Which would be the exact representation of:

AND cos.table_name NOT IN ('TABLE_1', 'TABLE_2')

There is no way of experimenting, cause a run of this Oracle package takes about 2 days...

Thanks in advance!

3
  • 2
    Possible duplicate of Declaration of multiple values in Oracle BIND Variables Commented Oct 9, 2015 at 14:12
  • 2
    I think you can find answer here - asktom.oracle.com/pls/asktom/… Commented Oct 9, 2015 at 14:15
  • The suggested duplicate question pertains to getting a list via a bind variable, in this case, it's a static list inside of PL/SQL which makes user-defined type more practical. Commented Oct 9, 2015 at 18:21

3 Answers 3

3

The best way to deal with a list of values like this is to use an array:

create or replace type t_table_list as table of varchar2(50);

FUNCTION Run
( i_PlafId  IN INTEGER
)
RETURN INTEGER
IS

l_tables_excl t_table_list := t_table_list('TABLE_1','TABLE_2');
...
AND cos.table_name NOT IN (select * from table(l_tables_excl))

You should note that the type must be created as a database object, not declared within a package.

Sign up to request clarification or add additional context in comments.

2 Comments

Seems very nice, but I get Error(240,34): PLS-00642: local collection types not allowed in SQL statements...
The type has to be created as a database object in order to be used in SQL. That means it must have its own create or replace, rather than just being declared in PL/SQL. If you can see the type in ALL_TYPES, then it's been created the right way.
0

Option A - Use LIKE

You can do a LIKE to see if the table name is in the string. Whether or not this works will depend on how similar your table names are.

/* Returns true if table name isn't a substring of l_tables.excl */
AND l_tables_excl NOT LIKE '%' || cos.table_name || '%'

Option B - Split string into table

Or you can split the string into a table and you'll be able to use NOT IN. It's a bit more difficult so I'll just give you references:

Testing note: If running your package takes two days, you might want to find a way of only doing a part of the work. Like if it processes a 1000 rows, add a variable to tell it to only do 100 rows just so it will finish. You really need to be able to test and two days is just too long.

Comments

0

You can use the REGEXP_LIKE function to simulate the in clause:

WHERE NOT REGEXP_LIKE(l_tables_excl, '(^|,)'||cos.table_name||'(,|$)')

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.