如何在SQL查询中使用Oracle关联数组

时间:2009-11-11 15:35:24

标签: sql oracle plsql associative-array odp.net

ODP.Net公开了将关联数组作为参数从C#传递到Oracle存储过程的能力。除非您尝试在sql查询中使用该关联数组中包含的数据,否则它是一个很好的功能。

原因是它需要一个上下文切换 - SQL语句需要SQL类型,并且传递到PL / SQL的关联数组实际上定义为PL / SQL类型。我相信在PL / SQL包/过程/函数中定义的任何类型都是PL / SQL类型,而在这些对象之外创建的类型是SQL类型(如果你可以提供更清晰的,请做但不是这个目标)问题)。

所以,问题是,您将使用什么方法将PL / SQL关联数组参数转换为可在sql语句中使用的过程中的内容,如下所示:

OPEN refCursor FOR
SELECT T.*
FROM   SOME_TABLE T,
       ( SELECT COLUMN_VALUE V
         FROM   TABLE( associativeArray )
       ) T2
WHERE  T.NAME = T2.V;

出于本示例的目的,“associativeArray”是由PLS_INTEGER索引的varchar2(200)的简单表。在C#中,associativeArry参数填充了字符串[]。

除了使用关联数组之外,请随意讨论其他方法,但提前知道这些解决方案将不被接受。不过,我很想看到其他选择。

2 个答案:

答案 0 :(得分:12)

我会创建一个这样的数据库类型:

create type v2t as table of varchar2(30);
/

然后在程序中:

FOR i IN 1..associativeArray.COUNT LOOP
    databaseArray.extend(1);
    databaseArray(i) := associativeArray(i);
END LOOP;

OPEN refCursor FOR
SELECT T.*
FROM   SOME_TABLE T,
       ( SELECT COLUMN_VALUE V
         FROM   TABLE( databaseArray )
       ) T2
WHERE  T.NAME = T2.V;

(其中databaseArray声明为v2t类型。)

答案 1 :(得分:1)

您不能在SQL范围中使用关联数组 - 它们只能在PL / SQL范围内使用。

一种方法是将关联数组映射到一个集合(如果在SQL范围中定义了集合类型而不是PL / SQL范围,则可以在SQL范围中使用它。)

<强> SQL

CREATE TYPE VARCHAR2_200_Array_Type AS TABLE OF VARCHAR2(200);
/

<强> PL / SQL

DECLARE
  TYPE associativeArrayType IS TABLE OF VARCHAR2(200) INDEX BY PLS_INTEGER;
  i                PLS_INTEGER;
  associativeArray associativeArrayType;
  array            VARCHAR2_200_Array_Type;
  cur              SYS_REFCURSOR;
BEGIN
  -- Sample data in the (sparse) associative array
  associativeArray(-2) := 'Test 1';
  associativeArray(0)  := 'Test 2';
  associativeArray(7)  := 'Test 3';

  -- Initialise the collection
  array := VARCHAR2_200_Array_Type();

  -- Loop through the associative array
  i := associativeArray.FIRST;
  WHILE i IS NOT NULL LOOP
    array.EXTEND(1);
    array(array.COUNT) := associativeArray(i);
    i := associativeArray.NEXT(i);
  END LOOP;

  -- Use the collection in a query
  OPEN cur FOR
    SELECT *
    FROM   your_table
    WHERE  your_column MEMBER OF array;
END;
/