【问题标题】:Use Type as output parameter for procedure使用 Type 作为过程的输出参数
【发布时间】:2021-12-30 09:40:05
【问题描述】:

我正在尝试返回一个类型作为输出参数,但出现错误: [错误] 编译(12:27):PLS-00382:表达式类型错误

代码如下:

create or replace TYPE OBJ_DCP FORCE as OBJECT (
  ID                           NUMBER,
  xxx_PROFILES_ID              NUMBER,
  DCP_NAME                     VARCHAR2(500 BYTE),
  L_R_NUMBER                   VARCHAR2(150 BYTE),
  STREET                       VARCHAR2(150 BYTE)
  };

create or replace TYPE T_DCP_TYPE as TABLE OF OBJ_DCP;

  create or replace procedure get_dcp_profiles(p_id in number, dcp_array_var OUT T_DCP_TYPE) is
    cursor c_dcp_profiles  is
      select * 
      from table1  ca -- table1 has same structure of OBJ_DCP 
      where ca.id = p_id;

    i number := 1;
  begin
    for r in c_dcp_profiles loop
      dcp_array_var(i) := r; -- this line is errored
      i := i + 1;
    end loop;
  end get_dcp_profiles;

【问题讨论】:

    标签: oracle plsql


    【解决方案1】:

    类型没问题。

    示例表:

    SQL> SELECT * FROM table1 ORDER BY id;
    
            ID XXX_PROFILES_ID D L S
    ---------- --------------- - - -
             1               1 a b c
             1               2 d e f
             2               3 x y z
    
    SQL>
    

    程序,修改:

    SQL> CREATE OR REPLACE PROCEDURE get_dcp_profiles (
      2     p_id           IN     NUMBER,
      3     dcp_array_var     OUT T_DCP_TYPE)
      4  IS
      5     CURSOR c_dcp_profiles IS
      6        SELECT *
      7          FROM table1 ca                 -- table1 has same structure of OBJ_DCP
      8         WHERE ca.id = p_id;
      9
     10     i      NUMBER := 1;
     11     l_arr  T_DCP_TYPE := T_DCP_TYPE ();
     12  BEGIN
     13     FOR r IN c_dcp_profiles
     14     LOOP
     15        l_arr.EXTEND;
     16        l_arr (i) :=
     17           OBJ_DCP (id               => r.id,
     18                    xxx_profiles_id  => r.xxx_profiles_id,
     19                    dcp_name         => r.dcp_name,
     20                    l_r_number       => r.l_r_number,
     21                    street           => r.street);
     22        i := i + 1;
     23     END LOOP;
     24
     25     dcp_array_var := l_arr;
     26  END get_dcp_profiles;
     27  /
    
    Procedure created.
    

    测试:

    SQL> SET SERVEROUTPUT ON
    SQL> DECLARE
      2     l_tab  t_dcp_type;
      3  BEGIN
      4     get_dcp_profiles (1, l_tab);
      5
      6     FOR i IN 1 .. l_tab.COUNT
      7     LOOP
      8        DBMS_OUTPUT.put_line (l_tab (i).id || ' ' || l_tab (i).dcp_name);
      9     END LOOP;
     10  END;
     11  /
    1 a
    1 d
    
    PL/SQL procedure successfully completed.
    
    SQL>
    

    【讨论】:

      【解决方案2】:

      您不需要使用光标或手动填充集合。

      如果将表声明为对象派生表:

      CREATE TABLE table1 OF OBJ_DCP;
      

      然后您可以将程序简化为:

      CREATE PROCEDURE get_dcp_profiles(
        p_id          IN  number,
        dcp_array_var OUT T_DCP_TYPE
      )
      IS
      BEGIN
        SELECT VALUE(ca)
        BULK COLLECT INTO dcp_array_var
        FROM   table1 ca
        WHERE  ca.id = p_id;
      END get_dcp_profiles;
      /
      

      对于样本数据:

      INSERT INTO table1 (id, xxx_Profiles_id, DCP_NAME, L_R_NUMBER, STREET)
      SELECT 1, 42, 'ABC name', 'ABC number', 'ABC street' FROM DUAL UNION ALL
      SELECT 1, 63, 'DEF name', 'DEF number', 'DEF street' FROM DUAL UNION ALL
      SELECT 2, 12, 'GHI name', 'GHI number', 'GHI street' FROM DUAL;
      

      然后:

      DECLARE
        dcps t_dcp_type;
      BEGIN
        get_dcp_profiles (1, dcps);
        FOR i IN 1 .. dcps.COUNT LOOP
          DBMS_OUTPUT.PUT_LINE (dcps(i).id || ' ' || dcps(i).dcp_name);
        END LOOP;
      END;
      /
      

      输出:

      1 ABC name
      1 DEF name
      

      如果您不想使用对象派生表,则可以使用:

      CREATE OR REPLACE PROCEDURE get_dcp_profiles(
        p_id          IN  number,
        dcp_array_var OUT T_DCP_TYPE
      )
      IS
      BEGIN
        SELECT OBJ_DCP(id, xxx_profiles_id, dcp_name, l_r_number, street)
        BULK COLLECT INTO dcp_array_var
        FROM   table1
        WHERE  id = p_id;
      END get_dcp_profiles;
      /
      

      db小提琴here

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-05
        • 1970-01-01
        相关资源
        最近更新 更多