sql >> Database >  >> RDS >> Oracle

Oracle - In CLAUSE-vraag bij gebruik met meerdere waarden, waardoor het dynamisch wordt

Als uw verzamelingstype is gedefinieerd in PL/SQL (in plaats van SQL), kunt u het helaas niet in SQL gebruiken omdat de SQL-engine niet weet hoe ermee om te gaan.

Als u in plaats daarvan het verzamelingstype in SQL hebt gedefinieerd, d.w.z.

CREATE TYPE varchar_tbl
    IS TABLE OF varchar2(40);

Dan kun je zoiets doen als

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

afhankelijk van de Oracle-versie - de syntaxis voor het gebruik van verzamelingen in SQL is in de loop van de tijd geëvolueerd - oudere versies van Oracle hadden een complexere syntaxis.

U kunt een PL/SQL-associatieve array (uw VARCHAR_ARRAY_TYPE) converteren naar een SQL-geneste tabelverzameling in PL/SQL, maar dat vereist iteratie door de associatieve array en het vullen van de geneste tabel, wat een beetje lastig is. Ervan uitgaande dat de VARCHAR_TBL geneste tafelverzameling is al gemaakt

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

je kunt de associatieve array converteren naar de geneste tabel en de geneste tabel gebruiken in een SQL-instructie zoals deze (met behulp van de SCOTT.EMP-tabel)

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;

Omdat het converteren tussen verzamelingstypen een beetje lastig is, kunt u echter beter de geneste tabelverzameling gebruiken (en die doorgeven aan de opgeslagen procedure), tenzij er een bepaalde reden is waarom de associatieve array nodig is.




  1. SQLite NOT NULL-beperking

  2. Wat is het verschil tussen MySQL Native Driver en MySQL Client Library?

  3. Overeenkomende matrixelementen uitsluiten

  4. Onverwachte vergrendeling voor tafel met primaire sleutel en unieke sleutel