sql >> Databasteknik >  >> RDS >> Oracle

Oracle - I CLAUSE fråga när du använder med flera värden, vilket gör det dynamiskt

Tyvärr, om din samlingstyp är definierad i PL/SQL (istället för SQL), kan du inte använda den i SQL eftersom SQL-motorn inte vet hur den ska hanteras.

Om du istället definierade samlingstypen i SQL, d.v.s.

CREATE TYPE varchar_tbl
    IS TABLE OF varchar2(40);

Då kan du göra något liknande

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

beroende på Oracle-versionen - syntaxen för att använda samlingar i SQL har utvecklats över tiden - hade äldre versioner av Oracle mer komplex syntax.

Du kan konvertera en PL/SQL associativ array (din VARCHAR_ARRAY_TYPE) till en SQL kapslad tabellsamling i PL/SQL, men det kräver att man itererar genom den associativa matrisen och fyller den kapslade tabellen, vilket är lite jobbigt. Förutsatt att VARCHAR_TBL kapslad tabellsamling har redan skapats

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

du kan konvertera från den associativa arrayen till den kapslade tabellen och använda den kapslade tabellen i en SQL-sats som denna (med SCOTT.EMP-tabellen)

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;

Eftersom det är lite jobbigt att konvertera mellan samlingstyper, skulle du generellt sett vara bättre av att bara använda den kapslade tabellsamlingen (och överföra den till den lagrade proceduren) om det inte finns en speciell anledning till att den associativa arrayen behövs.




  1. SQL rekursiv menysortering

  2. Mysql-lösenordet har upphört att gälla. Kan inte ansluta

  3. Docker postgres ogiltig primär checkpoint-post

  4. radera från databasen efter att webbläsaren stängts