我正在尝试从先前返回的记录表中获取列。但是,当我在程序包主体中运行代码时,出现以下错误:
ORA-06504: PL/SQL: Return types of Result Set variables or query do not match
但是,当我尝试在PL / SQL匿名块窗口中执行此操作时,可以使用Bulk Collect指令成功获取记录。
这是我成功的尝试,如我所说:
DECLARE
--
O_ref SYS_REFCURSOR;
-- Variable and types declaration.
TYPE REC_TYP is record (
column_1 number(8),
column_2 varchar2(13)
);
TYPE TAB_TYP is table of REC_TYP;
L_tab_typ TAB_TYP;
--
BEGIN
--
open O_ref for
select sku,
upc
from upc_ean
where sku = 2004030;
--
LOOP
--
FETCH O_ref BULK COLLECT into L_tab_typ;
EXIT WHEN L_tab_typ.COUNT = 0;
--
FOR indx IN 1 .. L_tab_typ.COUNT
LOOP
--
dbms_output.put_line('SKU: ' || L_tab_typ(indx).column_1);
dbms_output.put_line('UPC: ' || L_tab_typ(indx).column_2);
--
END LOOP;
--
END LOOP;
--
CLOSE O_ref;
--
END;
运行此代码时,我得到以下输出:
SKU: 2004030
UPC: 5601126003439
SKU: 2004030
UPC: 5601126039056
在包裹体内,我有以下东西:
为什么这在常规包装中不起作用?
FUNCTION GET_STORE_ITEMS(I_store IN number
----------- output ------------
O_item_data OUT NB_TAB_ITEM_DETAIL, -- i want to return a table type after I get the info from the sys_ref
----------- error -------------
O_error_message OUT VARCHAR2)
RETURN BOOLEAN IS
--
L_tab_type NB_TAB_ITEM_DETAIL;
L_sys_ref SYS_REFCURSOR;
L_test_sku number(8);
--
CURSOR C_GET_ITEMS IS
--
SELECT a.sku
FROM win_store a
WHERE a.store = I_store;
--
BEGIN
--
-- Loop over the fashion skus.
FOR R_items IN C_GET_ITEMS LOOP
--
BEGIN
--
IF GET_ITEM_DETAIL(I_store => I_store,
I_sku => R_items.sku,
O_item_data => L_sys_ref, -- returns a sys_refcursor with the same structure as the type
O_error_message => L_error_message) = FALSE THEN
--
O_error_message := NB_MESSGE40_SQL.EMESSAGE(L_error_message);
RETURN FALSE;
--
END IF;
--
LOOP
--
FETCH L_sys_ref BULK COLLECT into L_tab_type; -- It jumps to when others exception
EXIT WHEN L_tab_type.COUNT = 0;
--
FOR indx IN 1 .. L_tab_type.COUNT
LOOP
--
L_test_sku := L_tab_type(indx).sku;
--
END LOOP;
--
END LOOP;
--
END;
--
END LOOP;
--
RETURN TRUE;
--
EXCEPTION
--
WHEN OTHERS THEN
--
-- ...
RETURN FALSE;
--
END GET_STORE_ITEMS;
谢谢!
答案 0 :(得分:0)
我实际上是在解决问题。像在匿名块中一样,在获取sys_refcursor之前必须声明一个包规格级别的类型。
首先,在数据库中创建记录和表类型:
CREATE OR REPLACE TYPE NB_REC_ITEM_DETAIL AS OBJECT
(
column_1 number(8),
column_2 varchar2(13)
);
CREATE OR REPLACE TYPE NB_TAB_ITEM_DETAIL AS TABLE OF NB_REC_ITEM_DETAIL;
但是,对于PL / SQL引擎来说,这种结构是未知的,因此有必要在程序包规范中创建这些数据结构,如下所示:
TYPE REC_TYP is record (
column_1 number(8),
column_2 varchar2(13)
);
TYPE TAB_TYP is table of REC_TYP;
现在可以从sys_refcursor获取数据了。
FUNCTION GET_STORE_ITEMS(I_store IN NUMBER,
----------- output ------------
O_item_data OUT NB_TAB_ITEM_DETAIL,
----------- error -------------
O_error_message OUT VARCHAR2)
RETURN BOOLEAN IS
--
L_error_message VARCHAR2(255);
L_item_data_rec REC_TYP;
L_item_detail_ref SYS_REFCURSOR;
--
CURSOR C_GET_STORE_ITEMS IS
--
SELECT a.sku
FROM win_store a
WHERE a.store = I_store;
--
BEGIN
--
-- Instantiate output structure object.
--
O_item_data := NB_TAB_ITEM_DETAIL();
--
-- Loop over the items in the store range.
--
FOR R_items IN C_GET_STORE_ITEMS LOOP
--
BEGIN
--
IF NB_ITEM_INFO_SQL.GET_ITEM_DETAIL(I_store => I_store,
I_sku => R_items.sku,
I_ean => NULL,
O_item_data => L_item_detail_ref,
O_error_message => L_error_message) = FALSE THEN
--
O_error_message := NB_MESSGE40_SQL.EMESSAGE(L_error_message);
RETURN FALSE;
--
END IF;
--
-- Fetch info from item_data sys_refcursor to record type.
--
FETCH L_item_detail_ref INTO L_item_data_rec;
EXIT WHEN L_item_detail_ref%NOTFOUND;
--
CLOSE L_item_detail_ref;
--
O_item_data.extend();
O_item_data(O_item_data.last) := nb_rec_item_detail(column_1 => L_item_data_rec.column_1 ,
column_2 => L_item_data_rec.column_2);
--
END;
--
END LOOP;
--
RETURN TRUE;
--
EXCEPTION
--
WHEN OTHERS THEN
-- ...
RETURN FALSE;
--
--
END GET_STORE_ITEMS;