如何声明这是一个弱类型SYS_REFCURSOR变量的%ROWTYPE?(how to declar

2019-06-25 18:27发布

WRT代码下面我不能声明的类型取 - 进入 - 变量作为底层表的%ROWTYPE因为SYS_REFCURSOR是在选择连接两个表和还选择称为对底层两个表的属性的一些功能; 即我不能宣布为L_RECORD T%ROWTYPE

---
DECLARE
  P_RS SYS_REFCURSOR;
  L_RECORD P_RS%ROWTYPE;
BEGIN
  CAPITALEXTRACT(
    P_RS => P_RS
  );
    OPEN P_RS;
    LOOP
      BEGIN
        FETCH P_RS INTO L_RECORD;
        EXIT WHEN P_RS%NOTFOUND;
        ...
      EXCEPTION
        WHEN OTHERS THEN
        ...
      END;
    END LOOP;
    CLOSE P_RS;
END;
--------
CREATE or REPLACE PROCEDURE CAPITALEXTRACT
(
    p_rs OUT SYS_REFCURSOR
) AS
BEGIN
  OPEN p_rs for 
     select t.*,tminusone.*, f(t.cash), g(t.cash) FROM T t, TMINUSONE tminusone
    where t.ticket=tminusone.ticket;
END CAPITALEXTRACT;

当然,我不想定义与作为SYS_REFCURSOR返回,然后声明为L_RECORD R%ROWTYPE列的静态表R上。

因此这样的问题:如何声明这是一个弱类型SYS_REFCURSOR变量的%ROWTYPE?

Answer 1:

简短的回答是,你不能。 你需要定义一个变量为西港岛线返回每一列。

DECLARE
    P_RS SYS_REFCURSOR;
    L_T_COL1 T.COL1%TYPE;
    L_T_COL1 T.COL2%TYPE;
    ...

然后取入列的列表:

FETCH P_RS INTO L_T_COL1, L_T_COL2, ... ;

因为你知道你在裁判光标期待什么这是痛苦的,但管理作为长。 使用T.*在你的程序使得这个虽娇弱,如添加到表中的列会打破认为它知道什么列有代码和什么样的顺序他们在(你也可以打破它,如果表环境之间不建始终如一 - 我见过的地方列排序是不同在不同的环境)。 你可能想确保你只选择你真正关心反正列,以避免定义你从未看过的东西变量。

从11g中,您可以使用DBMS_SQL包到您转换sys_refcursorDBMS_SQL光标,你可以查询它来确定的列。 正如你可以做什么的例子,这将打印出每一列的值,每一行,列名为:

DECLARE
    P_RS SYS_REFCURSOR;
    L_COLS NUMBER;
    L_DESC DBMS_SQL.DESC_TAB;
    L_CURS INTEGER;
    L_VARCHAR VARCHAR2(4000);
BEGIN
    CAPITALEXTRACT(P_RS => P_RS);
    L_CURS := DBMS_SQL.TO_CURSOR_NUMBER(P_RS);
    DBMS_SQL.DESCRIBE_COLUMNS(C => L_CURS, COL_CNT => L_COLS,
        DESC_T => L_DESC);

    FOR i IN 1..L_COLS LOOP
        DBMS_SQL.DEFINE_COLUMN(L_CURS, i, L_VARCHAR, 4000);
    END LOOP;

    WHILE DBMS_SQL.FETCH_ROWS(L_CURS) > 0 LOOP
        FOR i IN 1..L_COLS LOOP
            DBMS_SQL.COLUMN_VALUE(L_CURS, i, L_VARCHAR);
            DBMS_OUTPUT.PUT_LINE('Row ' || DBMS_SQL.LAST_ROW_COUNT
                || ': ' || l_desc(i).col_name
                || ' = ' || L_VARCHAR);
        END LOOP;
    END LOOP;

    DBMS_SQL.CLOSE_CURSOR(L_CURS);
END;
/

这是没有多大实际用途,并且为了简洁,我把每个值作为一个字符串,因为我只是想反正打印。 看文档和寻找更多的实际应用的例子。

如果你只是想从你的参考光标你可以数列,我想,围绕循环l_desc并记录位置, column_name是不管你有兴趣,作为数字变量; 那么你可以通过该变量引用列后,你通常会在游标循环使用的名称。 取决于你的数据做什么。

但是,除非你期待不知道你要回来列的顺序,因为你似乎控制程序这是不可能的-假设你摆脱.*秒-你可能好得多减少返回到最小列你需要,只是宣布他们都分别。



文章来源: how to declare %ROWTYPE of a variable that is a weakly typed SYS_REFCURSOR?