Marciel,
É uma solução criativa, porém apresenta um problema de escalabilidade. Imagine se a tabela tiver X milhões de linhas, você terá que chamar a user-defined function X milhões de vezes e o desempenho do select vai para o espaço... Isso porque a query é simples, agora coloca joins e outras operações ali e já era.
Dá uma olhada na comparação de performance das soluções. Testei com 1 milhão de linhas, o que é bem pouco comparando com muitas tabelas por aí.
Selecionar tudo
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.4.0
Connected as fsitja
SQL>
SQL> SET SERVEROUTPUT ON
SQL> CREATE TABLE tab1 AS
2 SELECT LEVEL col1 FROM dual
3 CONNECT BY LEVEL < 1000000
4 /
Table created
SQL> CREATE OR REPLACE FUNCTION F_EXISTE (YSTRING IN VARCHAR2, YCOD IN NUMBER)
2 RETURN NUMBER IS
3 YAUX VARCHAR2 (4000) := YSTRING || ',';
4 YCONT NUMBER := 0;
5 YNUM NUMBER;
6 BEGIN
7 WHILE YCONT < LENGTH (YAUX) LOOP
8 YCONT := INSTR (YAUX, ',');
9 YNUM := TO_NUMBER (SUBSTR (YAUX,
10 1,
11 YCONT));
12
13 IF YNUM = YCOD THEN
14 RETURN 1;
15 END IF;
16
17 YAUX := SUBSTR (YAUX, YCONT + 1);
18 END LOOP;
19
20 RETURN 0;
21 END F_EXISTE;
22 /
Function created
SQL> CREATE OR REPLACE TYPE tab_number AS TABLE OF NUMBER
2 /
Type created
SQL> CREATE OR REPLACE FUNCTION in_list(p_in_list IN VARCHAR2) RETURN tab_number AS
2 v_tab tab_number := tab_number();
3 i NUMBER;
4 BEGIN
5 i := 1;
6 LOOP
7 v_tab.extend;
8 v_tab(v_tab.last) := regexp_substr(p_in_list, '[0-9]+', 1, i);
9 EXIT WHEN v_tab(v_tab.last) IS NULL;
10 i := i + 1;
11 END LOOP;
12 v_tab.trim;
13 RETURN v_tab;
14 END;
15 /
Function created
SQL> DECLARE
2 tab1 NUMBER;
3 t2 NUMBER;
4 qtty NUMBER;
5 BEGIN
6 tab1 := dbms_utility.get_time;
7 SELECT COUNT(*) INTO qtty FROM tab1 WHERE col1 IN (SELECT * FROM TABLE(in_list('2, 35, 4000')));
8 t2 := dbms_utility.get_time;
9 dbms_output.put_line(qtty || ' registros em ' || to_char((t2 - tab1) / 100, '990.000') || ' segundos');
10 tab1 := dbms_utility.get_time;
11 SELECT count(*) INTO qtty FROM tab1 WHERE f_existe('2, 35, 4000', col1) = 1;
12 t2 := dbms_utility.get_time;
13 dbms_output.put_line(qtty || ' registros em ' || to_char((t2 - tab1) / 100, '990.000') || ' segundos');
14 END;
15 /
3 registros em 0.280 segundos
3 registros em 10.410 segundos
PL/SQL procedure successfully completed
SQL> DROP TABLE TAB1;
Table dropped
SQL> DROP FUNCTION F_EXISTE;
Function dropped
SQL> DROP FUNCTION in_list;
Function dropped
SQL> DROP TYPE tab_number;
Type dropped
SQL>
De 0.28 segundos para 10.41.
Aline, para poder usar string como o Sérgio sugeriu, você precisa usar SQL dinâmico. Por isso não está funcionando.
Eu no seu lugar preferiria ficar com o SQL estático para não arrumar corda para me enforcar. Debugar SQL dinâmico é uma dor de cabeça desnecessária nesse caso.