Oracle
 sql >> Base de données >  >> RDS >> Oracle

Oracle - Dans la question CLAUSE lors de l'utilisation avec plusieurs valeurs, ce qui le rend dynamique

Malheureusement, si votre type de collection est défini en PL/SQL (plutôt qu'en SQL), vous ne pouvez pas l'utiliser en SQL car le moteur SQL ne sait pas comment le gérer.

Si à la place vous avez défini le type de collection en SQL, c'est-à-dire

CREATE TYPE varchar_tbl
    IS TABLE OF varchar2(40);

Ensuite, vous pouvez faire quelque chose comme

SELECT col1
  FROM table1 t1
 WHERE t1.id IN (SELECT column_value
                   FROM TABLE( <<variable of type varchar2_tbl>> ) )

selon la version d'Oracle - la syntaxe d'utilisation des collections dans SQL a évolué au fil du temps - les anciennes versions d'Oracle avaient une syntaxe plus complexe.

Vous pouvez convertir un tableau associatif PL/SQL (votre VARCHAR_ARRAY_TYPE) en une collection de tables imbriquées SQL en PL/SQL, mais cela nécessite de parcourir le tableau associatif et de remplir la table imbriquée, ce qui est un peu pénible. En supposant que le VARCHAR_TBL la collection de tables imbriquées a déjà été créée

SQL> CREATE OR REPLACE TYPE varchar_tbl
         IS TABLE OF varchar2(40);

vous pouvez convertir le tableau associatif en table imbriquée et utiliser la table imbriquée dans une instruction SQL comme celle-ci (en utilisant la table SCOTT.EMP)

declare
  type varchar_array_type
    is table of varchar2(40)
       index by binary_integer;
  l_associative_array varchar_array_type;
  l_index             binary_integer;
  l_nested_table      varchar_tbl := new varchar_tbl();
  l_cnt               pls_integer;
begin
  l_associative_array( 1 ) := 'FORD';
  l_associative_array( 10 ) := 'JONES';
  l_associative_array( 100 ) := 'NOT A NAME';
  l_associative_array( 75 ) := 'SCOTT';
  l_index := l_associative_array.FIRST;
  while( l_index IS NOT NULL )
  loop
    l_nested_table.EXTEND;
    l_nested_table( l_nested_table.LAST ) :=
             l_associative_array( l_index );
    l_index := l_associative_array.NEXT( l_index );
  end loop;
  SELECT COUNT(*)
    INTO l_cnt
    FROM emp
   WHERE ename IN (SELECT column_value
                     FROM TABLE( l_nested_table ) );
  dbms_output.put_line( 'There are ' || l_cnt || ' employees with a matching name' );
end;

Parce que la conversion entre les types de collection est un peu pénible, cependant, vous feriez mieux d'utiliser simplement la collection de tables imbriquées (et de la transmettre à la procédure stockée) à moins qu'il y ait une raison particulière pour laquelle le tableau associatif est nécessaire.