我在SQL Developer 3.2.20.09中测试包含2个特性的Oracle存储过程时遇到了问题:
存储过程签名:
TYPE ref_cursor_tst IS REF CURSOR;
TYPE arrWarningCode_tst IS TABLE OF VARCHAR2 (4000)
INDEX BY BINARY_INTEGER;
PROCEDURE SP_ITF_CU_DOCUMENT_Test (
p_projectNumber IN VARCHAR2,
p_tag IN VARCHAR2,
p_title IN VARCHAR2,
out_document_curs OUT ref_cursor_tst,
out_errorCode OUT VARCHAR2,
out_arrWarningCode OUT arrWarningCode_tst);
我最终的最佳测试代码:
set serveroutput on size 100000
DECLARE
docRef VARCHAR2(200);
outDocCurs PD360BADMIN.PKG_ITF_GENERAL_TST.ref_cursor_tst;
outErrorCode VARCHAR2(2000);
arrWarningCodes PD360BADMIN.PKG_ITF_GENERAL_TST.arrWarningCode_tst;
i PLS_INTEGER;
doc TBL_OBJECT%ROWTYPE;
BEGIN
dbms_output.put_line('debut de procedure');
docRef:= 'DOC-012';
arrWarningCodes.DELETE;
--call SP
PKG_ITF_GENERAL_TST.SP_ITF_CU_DOCUMENT_TEST (
p_projectNumber => 'XXX',
p_tag => docRef,
p_title => 'Doc title',
out_document_curs => outDocCurs,
out_errorCode => outErrorCode,
out_arrWarningCode => arrWarningCodes);
--print error code
dbms_output.put_line('out_errorCode=' || outErrorCode);
--print output cursor
--dbms_output.put_line(outDocCurs);
LOOP
FETCH outDocCurs INTO doc;
EXIT WHEN outDocCurs%NOTFOUND;
dbms_output.put_line(doc.OBJ_ID||','||doc.OBJ_TAG);
END LOOP;
--print warnings array
IF arrWarningCodes.count > 0 THEN
FOR i IN arrWarningCodes.FIRST .. arrWarningCodes.LAST LOOP
dbms_output.put_line('warning code=' || arrWarningCodes(i) );
END LOOP;
ENd IF;
dbms_output.put_line('fin de procedure');
END;
/
我得到的错误:
Error report:
ORA-06504: PL/SQL: Return types of Result Set variables or query do not match
ORA-06512: at line 30
06504. 00000 - "PL/SQL: Return types of Result Set variables or query do not match"
*Cause: Number and/or types of columns in a query does not match declared
return type of a result set variable, or declared types of two Result
Set variables do not match.
*Action: Change the program statement or declaration. Verify what query the variable
actually refers to during execution.
debut de procedure
out_errorCode=
我已经测试了几天的各种解决方案和语法,以及挖掘网络并需要来自不同来源的帮助但没有成功。
任何线索都会非常感激。
答案 0 :(得分:0)
假设TBL_OBJECT
是某个对象类型的表,其中包含两个字段obj_id
和obj_tag
;而且程序目前正在做类似的事情:
open out_document_curs for select * from tbl_object;
...然后有两种方法可以完成这项工作。第一种是更改您要获取的变量以匹配对象字段,而不是对象本身:
DECLARE
...
-- doc TBL_OBJECT%ROWTYPE;
doc_obj_id TBL_OBJECT.OBJ_ID%TYPE;
doc_obj_tag TBL_OBJECT.OBJ_TAG%TYPE;
BEGIN
...
然后更改提取和显示:
LOOP
FETCH outDocCurs INTO doc_obj_id, doc_obj_tag;
EXIT WHEN outDocCurs%NOTFOUND;
dbms_output.put_line(doc_obj_id||','||doc_obj_tag);
END LOOP;
如果对象有更多字段,那么您需要全部定义它们并在fetch中指定它们。
另一种方法是修改过程,使其返回一个对象类型:
open out_document_curs for select value(t) from tbl_object t;
然后你的调用匿名块将按原样工作,因为简单查询将返回对象本身而不是其中的字段。
您所做的将取决于程序的实际使用方式,而不是您的测试电话。
使用一些虚拟设置:
create type doc_obj as object (obj_id number, obj_tag varchar2(10));
/
create table tbl_object of doc_obj;
insert into tbl_object values (doc_obj(1, 'Test'));
虚拟包体,程序简化为:
PROCEDURE SP_ITF_CU_DOCUMENT_Test (
p_projectNumber IN VARCHAR2,
p_tag IN VARCHAR2,
p_title IN VARCHAR2,
out_document_curs OUT ref_cursor_tst,
out_errorCode OUT VARCHAR2,
out_arrWarningCode OUT arrWarningCode_tst)
IS
BEGIN
open out_document_curs for select value(o) from tbl_object o;
out_errorCode := 'OK';
out_arrWarningCode(1) := 'Danger!';
END SP_ITF_CU_DOCUMENT_Test;
然后完全按照问题中的方式调用代码(减去模式名称)给出:
anonymous block completed
debut de procedure
out_errorCode=OK
1,Test
warning code=Danger!
fin de procedure
使用另一种方法,使用对象字段的各个变量,也会得到相同的结果。