【问题标题】:How to transfer cursor to the procedure dynamically and to set rowtype variable dynamically?如何动态地将游标转移到过程并动态设置行类型变量?
【发布时间】:2016-03-24 05:48:09
【问题描述】:

我已经用动态设置游标和 %rowtype 变量编写了程序:

create or replace procedure process(source_table IN varchar2, my_cursor IN   sys_refcursor)
is

c sys_refCURSOR;
rec my_cursor%rowtype;

begin
Dbms_Output.put_line('process starts');
open c for 'select * from '||source_table;

loop
  fetch c into rec;  
  exit when c%notfound;
end loop;

close c;

  Dbms_Output.put_line('process is over');
end process;

我将光标转移到程序中,函数如下:

CREATE OR REPLACE FUNCTION ddp_get_allitems (source_table IN Varchar2)
  RETURN SYS_REFCURSOR
AS
  my_cursor SYS_REFCURSOR;
BEGIN
  OPEN my_cursor FOR 'SELECT * FROM '|| source_table;
  RETURN my_cursor;
END ddp_get_allitems;

编译过程“进程”时出现错误: PLS-00320 表达式类型的声明不完整或格式错误。 编译器已使用“rec my_cursor%rowtype;”突出显示该行。作为误差源。变量“source_table”和“my_cursor”基于同一个表(select * from my_table)。

那么为什么会出现错误以及如何消除它?

【问题讨论】:

  • 你不能这样做。 ref cursor 没有具体定义。它不是表格行。
  • 你的目标是什么?您可以使用包 DBMS_SQL 获取列,但不能为此使用 %ROWTYPE。
  • @Wernfried Domscheit:嗯,我有一个可变数量的表和可变数量的字段。而且我有使用静态表名和静态(明确声明)行类型的当前过程。我必须更改或重写它以使用可变参数(表和行类型变量)。

标签: oracle stored-procedures plsql


【解决方案1】:

只是想修改输出基本相同的 soe 参数 你想要达到的。基本上这里是我已经替换的功能 RETURN 类型为 TABLE TYPE,可以在过程 abd 中轻松调用 可以完成其余操作。如果这有帮助,请告诉我

--SQL Object creation
CREATE TYPE source_table_obj IS OBJECT 
(<TABLE_ATTRIBITES DECLARATION>);

--SQL TABLE type creation
CREATE TYPE source_table_tab IS TABLE OF source_table_obj;

--Function creation with nested table type as RETURN type
CREATE OR REPLACE FUNCTION ddp_get_allitems(
    source_table IN VARCHAR2)
  RETURN source_table_tab
AS
  src_tab source_table_tab;
BEGIN
  SELECT * BULK COLLECT INTO src_tab FROM source_table;
  RETURN src_tab;
END ddp_get_allitems;

-- Using Function's OUT param as an IN Param for Procedure an do all the requird processing
CREATE OR REPLACE PROCEDURE process(
    source_table IN VARCHAR2,
    src_tab_in   IN source_table_tab)
IS
BEGIN
  FOR i IN src_tab_in.FIRST..src_tab_in.LAST
  LOOP
    dbms_output.put_line('job processing');
  END LOOP;
END process;

【讨论】:

  • @Avrajit Roy:感谢您的回答。它看起来不错,但我看到一个缺点: --SQL 对象创建 CREATE TYPE source_table_obj IS OBJECT (); () - 需要显式声明表。但就我而言,我不知道传入表的确切表结构。在每种情况下,我都可以拥有可变数量的列或相同数量但不同类型的列。
【解决方案2】:

由于 PL/SQL 是静态类型的,编译器需要在编译时知道所有变量的类型。

因此没有高级元编程的空间。恐怕你做不到。

不过,在 SYS.STANDARD 中可以找到 generic 类型以及一些接受它们的内部函数。

  -- The following data types are generics, used specially within package
  -- STANDARD and some other Oracle packages.  They are protected against
  -- other use; sorry.  True generic types are not yet part of the language.

  type "<ADT_1>" as object (dummy char(1));
  type "<RECORD_1>" is record (dummy char(1));
  type "<TUPLE_1>" as object (dummy char(1));
  type "<VARRAY_1>" is varray (1) of char(1);
  type "<V2_TABLE_1>" is table of char(1) index by binary_integer;
  type "<TABLE_1>" is table of char(1);
  type "<COLLECTION_1>" is table of char(1);
  type "<REF_CURSOR_1>" is ref cursor;

以"&lt;ADT_1&gt;" 为例。有 XMLTYPE 构造函数或 DBMS_AQ ENQUEUE 和 DEQUEUE 函数。你可以在那里传递任何类型的对象。

目前你不能在自定义函数中使用这种数据类型,因为它们“还不是语言的一部分”,但也许有一天会有一些支持。

【讨论】:

  • @那个年轻人:谢谢你的回复:-)希望肯定已经死了...... :-)
猜你喜欢
  • 1970-01-01
  • 2013-05-15
  • 2020-06-18
  • 1970-01-01
  • 1970-01-01
  • 2014-07-27
  • 2011-10-28
  • 2019-01-29
  • 2019-08-31
相关资源
最近更新 更多