【问题标题】:Executing a query using a Collection as argument in Oracle在 Oracle 中使用集合作为参数执行查询
【发布时间】:2020-05-09 10:09:16
【问题描述】:

有什么方法可以立即执行以集合为参数的查询。

我想将类型定义为type my_type as table of number,然后使用execute immediate QUERY using COLLECTION 执行动态查询(通过连接适当的部分创建)。

当我编写这样的代码时,我得到PLS-00457 expressions has to be of SQL types

【问题讨论】:

  • 如果您 edit 提出您的问题并发布您编写的代码,我也许可以告诉您为什么您会收到 Oracle 错误 PLS-00457
  • 请问您可以显示查询吗?
  • 您使用的是什么版本的 Oracle? Oracle 12c 在 SQL 和 PL/SQL 包类型之间引入了更好的兼容性。在 11g 中,您可能必须将类型定义为 SQL 对象才能完成这项工作。

标签: oracle plsql dynamicquery varray


【解决方案1】:

来自 oracle 文档:https://docs.oracle.com/cd/B12037_01/appdev.101/b10807/11_dynam.htm 示例 7-4 对象类型和集合的动态 SQL

下面的例子说明了对象和集合的使用。假设你定义了对象类型 Person 和 VARRAY 类型的 Hobbies,如下:

CREATE TYPE Person AS OBJECT (name VARCHAR2(25), age NUMBER);
CREATE TYPE Hobbies IS VARRAY(10) OF VARCHAR2(25);

使用动态 SQL,您可以编写使用这些类型的包:

CREATE OR REPLACE PACKAGE teams AS
   PROCEDURE create_table (tab_name VARCHAR2);
   PROCEDURE insert_row (tab_name VARCHAR2, p Person, h Hobbies);
   PROCEDURE print_table (tab_name VARCHAR2);
END;
/

CREATE OR REPLACE PACKAGE BODY teams AS
   PROCEDURE create_table (tab_name VARCHAR2) IS
   BEGIN
      EXECUTE IMMEDIATE 'CREATE TABLE ' || tab_name ||
         ' (pers Person, hobbs Hobbies)';
   END;

   PROCEDURE insert_row (
      tab_name VARCHAR2,
      p Person,
      h Hobbies) IS
   BEGIN
      EXECUTE IMMEDIATE 'INSERT INTO ' || tab_name ||
         ' VALUES (:1, :2)' USING p, h;
   END;

   PROCEDURE print_table (tab_name VARCHAR2) IS
      TYPE RefCurTyp IS REF CURSOR;
      cv RefCurTyp;
      p  Person;
      h  Hobbies;
   BEGIN
      OPEN cv FOR 'SELECT pers, hobbs FROM ' || tab_name;
      LOOP
         FETCH cv INTO p, h;
         EXIT WHEN cv%NOTFOUND;
         -- print attributes of 'p' and elements of 'h'
      END LOOP;
      CLOSE cv;
   END;
END;
/

从匿名块中,您可以调用包 TEAMS 中的过程:

DECLARE
   team_name VARCHAR2(15);
BEGIN
   team_name := 'Notables';
   teams.create_table(team_name);
   teams.insert_row(team_name, Person('John', 31),
      Hobbies('skiing', 'coin collecting', 'tennis'));
   teams.insert_row(team_name, Person('Mary', 28),
      Hobbies('golf', 'quilting', 'rock climbing'));
   teams.print_table(team_name);
END;
/

【讨论】:

    【解决方案2】:

    是的,你可以这样做,但是 1) 类型应定义为 OBJECT 2)Oracle版本应为11g或更高 3)如果你的动态块有plsql代码,你可以在动态块变量中分配这个集合值,然后使用它 4)如果你的动态块只是一些sql,你需要先使用Table(collection)关键字将集合转换为表

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-02-24
      • 1970-01-01
      • 2022-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多