存储LOOP的每次迭代的数据并在ref游标上返回所有这些数据?

时间:2017-08-17 18:59:19

标签: sql oracle plsql oracle-sqldeveloper

对不起的问题名称抱歉,我将举一个更具体的例子。

 var1 VARCHAR(20);
 var2 VARCHAR(20);

  --MYRECORD CONTAINS COLUMNS ELEMENT0, VAL

     FOR MYRECORD IN EXPLICITCURSOR LOOP
     SELECT COL1, COL2 INTO var1, var2 FROM table1 WHERE table1.COLUMNT=MYRECORD.VAL;
     END LOOP;

正如你所看到的,我有一个LOOP,在里面我有一个SELECT。到目前为止,为了测试,我将结果保存为每次都被覆盖的两个变量。 我需要保存每次迭代(ELEMENT0,COL1,COL2),并且我在输出时用REF CURSOR给它们。

EDIT1:我现在正在寻找定义记录类型的RECORD和TABLE的可能性。谁能给我一个案例的例子?我在将表设置为输出参数时遇到问题。 这是我在包装开始时准备的。

TYPE my_record is RECORD(
   ELEMENT0      varchar2(20),
   COL1          varchar2(20),
   COL2          varchar2(20));

TYPE my_table IS TABLE OF my_record;

现在我在我的程序中使用OUT参数:

TABLERESULT                            OUT my_table

我试图以这种方式在LOOP的每次迭代中将我的三个varchar值插入到我的OUT参数中(值设置正确):

INSERT INTO TABLERESULT(ELEMENT0,COL1,COL2) VALUES(ELEMENT0,COL1,COL2);

它给了我错误:

PL/SQL: ORA-00942: table or view does not exist

我使用这种类型的OUT参数做错了吗?

有什么建议吗?谢谢。 (我使用的是Oracle 11g)

EDIT2:在@APC的帮助下,我发现命名错误,现在编译器没有给出问题。我会继续,我会告诉你。

2 个答案:

答案 0 :(得分:0)

创建与记录结构匹配的对象类型。

创建这些对象类型的嵌套表类型。

对于每个字符串连字符,请添加到数组中。

然后返回一个游标变量,如下所示:

OPEN cv FOR SELECT FROM TABLE(my_array); 返回cv;

table函数将数组转换为可以分配给游标变量的结果集。

这是一个LiveSQL脚本的链接,它将运行您在下面看到的代码: https://livesql.oracle.com/apex/livesql/file/content_FFTOKNC4AHGPOQE79FF76S7EQ.html

CREATE OR REPLACE TYPE three_ot
   AUTHID DEFINER IS OBJECT
(
   element0 VARCHAR2 (200),
   col1 VARCHAR2 (200),
   col2 VARCHAR2 (200)
)
/

CREATE OR REPLACE TYPE three_nt IS TABLE OF three_ot
/

CREATE OR REPLACE FUNCTION data_for_you
   RETURN SYS_REFCURSOR
   AUTHID DEFINER
IS
   l_cursor   SYS_REFCURSOR;
   l_nt       three_nt;
BEGIN
   SELECT three_ot (TO_CHAR (employee_id), last_name, first_name)
     BULK COLLECT INTO l_nt
     FROM hr.employees;

   OPEN l_cursor FOR SELECT * FROM TABLE (l_nt);

   RETURN l_cursor;
END;
/

DECLARE
   l_cursor   SYS_REFCURSOR := data_for_you ();
   l_three    three_ot;
   element0   VARCHAR2 (200);
   col1       VARCHAR2 (200);
   col2       VARCHAR2 (200);
BEGIN
   LOOP
      FETCH l_cursor INTO element0, col1, col2;
      EXIT WHEN l_cursor%NOTFOUND;
      DBMS_OUTPUT.put_line (col1);
   END LOOP;

   CLOSE l_cursor;
END;
/

答案 1 :(得分:0)

这可以简单地实现,无需任何迭代。 希望下面片段有帮助。请原谅任何语法错误,因为我没有任何工作空间来执行此命令。

--Wwhat i would suggest is rather going row-by-row this can be achieved by single iteration and can be returnedas ref cursor as output.

DECLARE
  lv sys.odcivarchar2list;
  lv_ref sys_refcursor;
BEGIN
  SELECT val BULK COLLECT
  INTO lv
  FROM TABLE2;

  OPEN lv_ref FOR SELECT * FROM TABLE1 WHERE TABLE1.COL IN
  (SELECT COLUMN_VALUE FROM TABLE(lv)
  );
END;
/