为什么我收到 ORA-06531: 对未初始化集合的引用?

ass*_*sia 3 oracle plsql oracle12c

我想调用 PL/SQL 函数

\n
select consult_trac.get_detail_dos_amo('12345') from dual\n
Run Code Online (Sandbox Code Playgroud)\n

但我收到错误:

\n
\n

java.sql.SQLException: ORA-06530: 引用未初始化的组合
\nORA-06512: \xc3\xa0 "CNSS_SERVICES.GET_DETAIL_DOS_AMO" 第 60 行 (ret(v_counter).num_doss := DS_DT.NUM_DOSS;)

\n
\n

我的 PL/SQL 函数是在包含所有类型的包中定义的。

\n

包定义:

\n
CREATE OR REPLACE PACKAGE consult_trac AS\n\nFUNCTION get_detail_dos_amo (p_num_doss VARCHAR2)\n      RETURN tab_dos_t_amo;\n\nEND consult_trac;\n/\n\nCREATE OR REPLACE PACKAGE BODY consult_trac AS\n    FUNCTION get_detail_dos_amo (p_num_doss VARCHAR2)\n      RETURN tab_dos_t_amo\n      IS\n      CURSOR DOSS_DET (num_doss VARCHAR2) IS\n        SELECT NUM_DOSS,\n               DAT_DEP,\n               NUM_IMMA,\n               NUM_IND,\n               P_DATE_ACTE,\n               CODE_EVOP,\n               LIB_EVOP,\n               CODE_DR,\n               LIB_DR,\n               C_USER,\n               C_GENCE,\n               C_NIV,\n               L_NIV,\n               DAT_SUI,\n               C_D_ETAT,\n               L_D_ETAT,\n               L_NAT,\n               NUM_RECOM,\n               ACCUSE,\n               P_MONTANT,\n               NUM_D_PARENT,\n               P_INP_DOS,\n               P_ICE_DOS,\n               P_CIN,\n               P_NOM,\n               P_PRENOM,\n               P_N_PAGE,\n               P_D_SORTIE,\n               P_C_CAT,\n               P_C_SOURCE,\n               C_ERROR\n        FROM   TYP_DOSS_AMO\n        WHERE  NUM_DOSS = p_num_doss;\n      \n      CURSOR SEL_MEDIC(num_doss   VARCHAR2) IS\n        SELECT CODE_MEDIC, \n               NOMBRE \n        FROM DOSS_MEDIC\n        WHERE NUM_DOSS = num_doss;\n      \n      CURSOR SEL_INP(num_doss   VARCHAR2) IS\n        SELECT CODE_INP\n        FROM DOSS_INP\n        WHERE NUM_DOSS = num_doss;\n        \n      ret tab_dos_t_amo;\n      ret_med tab_medic; \n      ret_inp tab_inp;\n      v_counter number := 0;\n      v_counter_med number := 0;\n      v_counter_inp number := 0;\n    BEGIN\n      FOR DS_DT IN DOSS_DET(p_num_doss) \n            LOOP\n                ret(v_counter).num_doss := DS_DT.NUM_DOSS;\n                ret(v_counter).dat_dep := DS_DT.DAT_DEP;\n                ret(v_counter).num_imma := DS_DT.NUM_IMMA;\n                ret(v_counter).num_ind := DS_DT.NUM_IND;\n                ret(v_counter).p_date_acte := DS_DT.P_DATE_ACTE;\n                ret(v_counter).code_evop := DS_DT.CODE_EVOP;\n                ret(v_counter).lib_evop := DS_DT.LIB_EVOP;\n                ret(v_counter).code_dr := DS_DT.CODE_DR;\n                ret(v_counter).lib_dr := DS_DT.LIB_DR;\n                ret(v_counter).c_user := DS_DT.C_USER;\n                ret(v_counter).c_gence := DS_DT.C_GENCE;\n                ret(v_counter).c_niv := DS_DT.C_NIV;\n                ret(v_counter).l_niv := DS_DT.L_NIV;\n                ret(v_counter).dat_sui := DS_DT.DAT_SUI;\n                ret(v_counter).c_d_etat := DS_DT.C_D_ETAT;\n                ret(v_counter).l_d_etat := DS_DT.L_D_ETAT;\n                ret(v_counter).l_nat := DS_DT.L_NAT;\n                ret(v_counter).num_recom := DS_DT.NUM_RECOM;                \n                ret(v_counter).accuse := DS_DT.ACCUSE;  \n                ret(v_counter).p_montant := DS_DT.P_MONTANT;\n                ret(v_counter).num_d_parent := DS_DT.NUM_D_PARENT;\n                ret(v_counter).p_INP_dos := DS_DT.P_INP_DOS;\n                ret(v_counter).p_ICE_dos := DS_DT.P_ICE_DOS;\n                ret(v_counter).p_cin := DS_DT.P_CIN;\n                ret(v_counter).p_nom := DS_DT.P_NOM;\n                ret(v_counter).p_prenom := DS_DT.P_PRENOM;\n                ret(v_counter).p_n_page := DS_DT.P_N_PAGE;\n                ret(v_counter).p_d_sortie := DS_DT.P_D_SORTIE;\n                ret(v_counter).p_c_cat := DS_DT.P_C_CAT;\n                ret(v_counter).p_c_source := DS_DT.P_C_SOURCE;\n                ret(v_counter).c_error := DS_DT.C_ERROR;\n                \n                FOR SM IN SEL_MEDIC(p_num_doss)\n                    LOOP\n                        ret_med(v_counter_med).code_medic := SM.CODE_MEDIC;\n                        ret_med(v_counter_med).nombre := SM.NOMBRE;\n                        v_counter_med := v_counter_med +1;\n                    END LOOP;\n                FOR SI IN SEL_INP(p_num_doss)\n                    LOOP\n                        ret_inp(v_counter_inp).code_inp := SI.CODE_INP;\n                        v_counter_inp := v_counter_inp +1;\n                    END LOOP;\n                ret(v_counter).p_tab_medic := ret_med;\n                ret(v_counter).p_tab_inp := ret_inp;\n                v_counter := v_counter + 1;\n            END LOOP;\n\n        return ret;\n    END;\n   \nEND consult_trac;\n/\n
Run Code Online (Sandbox Code Playgroud)\n

类型:

\n
create or replace TYPE MEDIC AS OBJECT (\n    num_doss   VARCHAR2(9),\n    code_medic VARCHAR2(10),\n    nombre     NUMBER);\n\ncreate or replace TYPE tab_medic IS TABLE OF MEDIC;\n\ncreate or replace TYPE INP AS OBJECT (\n    num_doss   VARCHAR2(9),\n    code_inp   VARCHAR2(20));\n\ncreate or replace TYPE tab_INP IS TABLE OF INP;\n\ncreate or replace TYPE TYP_DOS_AMO AS OBJECT (\n        num_doss   VARCHAR2(9),\n        dat_dep    DATE,\n        num_imma   VARCHAR2(13),\n        num_ind    VARCHAR2(20),\n        p_date_acte  DATE,\n        code_evop  VARCHAR2(20),\n        lib_evop   VARCHAR2(30),\n        code_dr    VARCHAR2(20),\n        lib_dr     VARCHAR2(30),\n        c_user     VARCHAR2(20),\n        c_gence    VARCHAR2(20),\n        c_niv      VARCHAR2(20),\n        l_niv      VARCHAR2(20),\n        dat_sui    DATE,\n        c_d_etat   VARCHAR2(20),\n        l_d_etat   VARCHAR2(20),\n        l_nat      VARCHAR2(30),\n        num_recom  VARCHAR2(30),\n        accuse     VARCHAR2(30),\n        p_montant  VARCHAR2(20),\n        num_d_parent VARCHAR2(9),\n        p_INP_dos  VARCHAR2(20),\n        p_ICE_dos  VARCHAR2(20),\n        p_cin      VARCHAR2(10),\n        p_nom      VARCHAR2(20),\n        p_prenom   VARCHAR2(20),\n        p_n_page   VARCHAR2(20),              \n        p_d_sortie DATE,\n        p_c_cat    VARCHAR2(15),\n        p_c_source VARCHAR2(15),\n        p_tab_medic tab_medic,\n        p_tab_inp   tab_inp,\n        c_error    INTEGER\n);\n    \ncreate or replace TYPE tab_INP IS TABLE OF INP;\n
Run Code Online (Sandbox Code Playgroud)\n

Con*_*ald 6

嵌套表对象与关联数组不同,因此必须在使用前对其进行初始化。

因此

ret tab_dos_t_amo
Run Code Online (Sandbox Code Playgroud)

可能需要

ret tab_dos_t_amo := tab_dos_t_amo();
Run Code Online (Sandbox Code Playgroud)

现在,当您想向其中添加元素时,您需要向数组添加索引,例如

ret.extend;
Run Code Online (Sandbox Code Playgroud)

现在允许您引用 ret(1)。

您没有向我们展示 tab_dos_t_amo 的定义,但我认为它是 dos_t_amo 的表。因此该表中的每个条目都是一个对象,这意味着您的代码:

            ret(v_counter).num_doss := DS_DT.NUM_DOSS;
            ret(v_counter).dat_dep := DS_DT.DAT_DEP;
            ret(v_counter).num_imma := DS_DT.NUM_IMMA;
Run Code Online (Sandbox Code Playgroud)

现在看起来像

            ret.extend;
            ret(v_counter) := dos_t_amo(
                                  DS_DT.DAT_DEP,
                                  DS_DT.NUM_IMMA,
                                  ...
                                  ...);
Run Code Online (Sandbox Code Playgroud)