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

发布于 2024-08-10 20:09:57 字数 714 浏览 3 评论 0原文

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 参数由 string[] 填充。

除了使用关联数组之外,请随意讨论其他实现此目的的方法,但请提前了解这些解决方案将不会被接受。尽管如此,我还是有兴趣看看其他选择。

ODP.Net exposes the ability to pass Associative Arrays as params into an Oracle stored procedure from C#. Its a nice feature unless you are trying to use the data contained within that associative array in a sql query.

The reason for this is that it requires a context switch - SQL statements require SQL types and an associative array passed into PL/SQL like this is actually defined as a PL/SQL type. I believe any types defined within a PL/SQL package/procedure/function are PL/SQL types while a type created outside these objects is a SQL type (if you can provide more clarity on that, please do but its not the goal of this question).

So, the question is, what are the methods you would use to convert the PL/SQL associative array param into something that within the procedure can be used in a sql statement like this:

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

For the purposes of this example, the "associativeArray" is a simple table of varchar2(200) indexed by PLS_INTEGER. In C#, the associativeArry param is populated with a string[].

Feel free to discuss other ways of doing this besides using an associative array but know ahead of time those solutions will not be accepted. Still, I'm interested in seeing other options.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

凉栀 2024-08-17 20:09:57

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

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类型。)

I would create a database type like this:

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

And then in the procedure:

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;

(where databaseArray is declared to be of type v2t.)

缱倦旧时光 2024-08-17 20:09:57

您不能在 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;
/

You cannot use associative arrays in the SQL scope - they are only usable in the PL/SQL scope.

One method is to map the associative array to a collection (which can be used in the SQL scope if the collection type has been defined in the SQL scope and not the PL/SQL scope).

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;
/
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文