Oracle - 在使用多个值时的CLAUSE问题中,使其成为动态的

sar*_*ake 4 oracle in-clause

我只是在谷歌上花了一个小时,在这里试图直接回答如何在Oracle中做到这一点.我需要的是能够使用自动构造的select in子句,如

select col1 from table1 where id.table IN ('1','2','3');
Run Code Online (Sandbox Code Playgroud)

其中id值传递给数组内的存储过程.关联数组已定义为:

 TYPE varchar_array_type IS TABLE OF VARCHAR2 (40)      INDEX BY BINARY_INTEGER;
Run Code Online (Sandbox Code Playgroud)

有没有一种简单,具体的方法呢?谢谢

Jus*_*ave 5

不幸的是,如果您的集合类型是在PL/SQL(而不是SQL)中定义的,则不能在SQL中使用它,因为SQL引擎不知道如何处理它.

相反,您在SQL中定义了集合类型,即

CREATE TYPE varchar_tbl
    IS TABLE OF varchar2(40);
Run Code Online (Sandbox Code Playgroud)

然后你可以做类似的事情

SELECT col1
  FROM table1 t1
 WHERE t1.id IN (SELECT column_value
                   FROM TABLE( <<variable of type varchar2_tbl>> ) )
Run Code Online (Sandbox Code Playgroud)

取决于Oracle版本 - 在SQL中使用集合的语法随着时间的推移而发展 - 旧版本的Oracle具有更复杂的语法.

您可以将PL/SQL关联数组(您的VARCHAR_ARRAY_TYPE)转换为PL/SQL中的SQL嵌套表集合,但这需要迭代关联数组并填充嵌套表,这有点痛苦.假设VARCHAR_TBL已经创建了嵌套表集合

SQL> CREATE OR REPLACE TYPE varchar_tbl
         IS TABLE OF varchar2(40);
Run Code Online (Sandbox Code Playgroud)

你可以从关联数组转换为嵌套表,并在这样的SQL语句中使用嵌套表(使用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;
Run Code Online (Sandbox Code Playgroud)

但是,因为在集合类型之间进行转换有点麻烦,所以通常最好只使用嵌套表集合(并将其传递给存储过程),除非有特殊原因需要关联数组.