【问题标题】:inconsistent datatypes: when returning table from cursor in a package function - ORACLE不一致的数据类型:从包函数中的游标返回表时 - ORACLE
【发布时间】:2016-09-14 06:57:22
【问题描述】:

我有以下包裹。我正在尝试从游标填充函数内部的记录并返回记录。我不确定如何将游标中的行分配到记录变量中。我需要返回记录,以便可以从中创建物化视图。

CREATE OR REPLACE PACKAGE pkg_contrator_of_consultant AS

    TYPE cst_record IS RECORD(
       consultant_id NUMBER(10));

    TYPE cst_id_type IS TABLE OF cst_record;

    FUNCTION fnc_get_contractor_id(cst_username IN VARCHAR2)
        RETURN cst_id_type
        PIPELINED;
END;


CREATE OR REPLACE PACKAGE BODY pkg_contrator_of_consultant AS 

    FUNCTION fnc_get_contractor_id(cst_username IN VARCHAR2 )
        RETURN cst_id_type
        PIPELINED IS    

        V_cursor_contracotr_id cst_id_type;

        CURSOR cursor_contract_name IS
        SELECT plc.FK2_CONTRACTOR_ID
            FROM lds_consultant cons
            INNER JOIN lds_account acc on cons.consultant_id = acc.fk1_consultant_id 
            INNER JOIN lds_placement plc on acc.account_id = plc.FK1_ACCOUNT_ID
            WHERE UPPER(cons.USERNAME) = UPPER(cst_username)
            AND UPPER(plc.PLT_TO_PERMANENT) = UPPER('Y');

            V_contracotr_id cst_id_type;
        BEGIN

            FOR rec IN cursor_contract_name LOOP

                V_contracotr_id := rec.fk2_contractor_id;

                SELECT V_contracotr_id INTO V_cursor_contracotr_id FROM DUAL;

                dbms_output.put_line('cst_username : '||cst_username||'  V_contracotr_id :'||V_contracotr_id);


            END LOOP;

            PIPE ROW (V_cursor_contracotr_id);
            RETURN;
        END fnc_get_contractor_id;
    END;
    /

排队

V_contracotr_id := rec.fk2_contractor_id;

当光标选择的列是 NUMBER 类型时,它会给出错误“不一致的数据类型:预期的 UDT 得到 NUMBER”。

FK2_CONTRACTOR_ID   NUMBER

【问题讨论】:

  • 就个人而言,我会返回一个引用游标,而不是一个表。这样,您就不会做两次工作,一次在 pl/sql 中,一次在物化视图中。
  • 是 sys_refcursor 类型的吗?
  • 工作与refcursor proc或表函数相同。表函数的好处是可以在 SQL 中进一步操作结果集,甚至可以连接到其他表或其他 TFN。使跨应用程序重用和模块化复杂逻辑变得更加容易。
  • 这只是一个例子吗?对于单个属性,您不需要 RECORD 类型。请改用TYPE cst_id_type IS TABLE OF NUMBER(10);。在这种情况下,列名是COLUMN_VALUE
  • 是的,这是一个练习。

标签: sql oracle function package


【解决方案1】:

试试这个:

        out_rec cst_record;

        CURSOR C1 IS
        SELECT ...;

  BEGIN

    open c1;
    LOOP
    FETCH c1 INTO out_rec;

  exit when c1%notfound;

    PIPE ROW(out_rec);

  END LOOP;

  close c1;

  RETURN;

END fnc_get_contractor_id;

更新代码:

CREATE OR REPLACE PACKAGE pkg_contrator_of_consultant AS

    TYPE cst_record IS RECORD(
       consultant_id NUMBER(10));

    TYPE cst_id_type IS TABLE OF cst_record;

    FUNCTION fnc_get_contractor_id(cst_username IN VARCHAR2)
        RETURN cst_id_type
        PIPELINED;
END;
/

CREATE OR REPLACE PACKAGE BODY pkg_contrator_of_consultant AS 
FUNCTION fnc_get_contractor_id(cst_username IN VARCHAR2 )
    RETURN cst_id_type
    PIPELINED IS    

    CURSOR c1 IS
    SELECT plc.FK2_CONTRACTOR_ID
        FROM lds_consultant cons
        INNER JOIN lds_account acc on cons.consultant_id = acc.fk1_consultant_id 
        INNER JOIN lds_placement plc on acc.account_id = plc.FK1_ACCOUNT_ID
        WHERE UPPER(cons.USERNAME) = UPPER(cst_username)
        AND UPPER(plc.PLT_TO_PERMANENT) = UPPER('Y');

        out_rec cst_record;
    BEGIN

        open c1;
        LOOP
        FETCH c1 INTO out_rec;

      exit when c1%notfound;

        PIPE ROW(out_rec);

      END LOOP;

      close c1;

      RETURN;

    END fnc_get_contractor_id;
END;
/

【讨论】:

  • 我仍然收到错误“INTO 列表中的表达式 'V_CONTRACOTR_ID' 的类型错误”。我什至有与光标选择的列相同的用户定义类型。
  • 试试我给你的代码。里面没有“V_CONTRACOTR_ID”。
  • 同样的错误。我刚刚将 out_rect 重命名为“V_CONTRACTOR_ID”。
  • 您能否粘贴您现在正在执行的确切代码?
  • 您需要两种类型 - 记录和表,并且 OUT_REC 应该是记录类型。您的 RETURN 是正确的 - 表格类型。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多