我有一个存储过程调用一个返回SYS_REFCURSOR的函数。该函数返回一个SYS_REFCURSOR,因为此函数也是从Java应用程序调用的,Java不理解rowtype。
这是我的功能。
function f_get_building(
p_building_id in T_BUILDING.ID%type
) return sys_refcursor
AS
v_cursor sys_refcursor;
BEGIN
open v_cursor for
select
BUILDING_ID,
CAMPUS_ID,
DELETE_FLAG,
max(EFFECTIVE_DATE),
END_DATE,
IMAGE_URL,
INSTITUTION_ID,
LOCAL_ID,
LOCATION_ID,
NAME
from V_BUILDING
where BUILDING_ID = p_building_id
group by
BUILDING_ID,
CAMPUS_ID,
DELETE_FLAG,
END_DATE,
IMAGE_URL,
INSTITUTION_ID,
LOCAL_ID,
LOCATION_ID,
NAME;
return v_cursor;
END f_get_building;
在另一个存储过程中,我也在调用此函数,但在使用它时遇到问题。这是存储过程。
procedure sp_delete_building(
p_building_id in T_BUILDING.ID%type,
p_permanent_delete in boolean default false
)
AS
v_building_cur sys_refcursor;
v_building_rec V_BUILDING%rowtype;
BEGIN
-- if permanment delete
if p_permanent_delete = true
then
delete from T_BUILDING where ID = p_building_id;
-- otherwise perform soft delete
else
-- lookup
v_building_cur := f_get_building(p_building_id);
-- if cursor is empty there is nothing to do
if v_building_cur%notfound then
return;
end if;
fetch v_building_cur into v_building_rec; -- this line is where the error happens
-- if its already deleted nothing to do
if v_building_rec.DELETE_FLAG = 'Y'
then
return;
else
insert into T_BUILDING_ATTRIBUTE(BUILDING_ID,EFFECTIVE_DATE,DELETE_FLAG,
IMAGE_URL,LOCATION_ID,NAME)
values (v_building_rec.BUILDING_ID,current_timestamp,'Y',v_building_rec.IMAGE_URL
,v_building_rec.LOCATION_ID,v_building_rec."NAME");
end if;
end if;
END sp_delete_building;
我正在获得以下PL / SQL堆栈跟踪。
ORA-01722: invalid number
ORA-06512: at "OBR.PKG_BUILDING", line 114
ORA-06512: at line 8
原谅我的无知,这是我的第一个使用PL / SQL的项目,我将自己归类为Java开发人员,而不是数据库开发人员。因为我从V_BUILDING中选择了所有内容,所以我希望我能将它作为存储过程中的rowtype。如何在存储过程中使用我的函数?
更新
这是V_BUILDING的创建语句
CREATE OR REPLACE FORCE VIEW "OBR"."V_BUILDING" ("BUILDING_ID", "LOCAL_ID", "INSTITUTION_ID", "EFFECTIVE_DATE", "END_DATE", "DELETE_FLAG", "CAMPUS_ID", "LOCATION_ID", "IMAGE_URL", "NAME") AS
SELECT
ba.BUILDING_ID,
b.LOCAL_ID,
b.INSTITUTION_ID,
ba.EFFECTIVE_DATE,
NVL(MIN(ba2.EFFECTIVE_DATE - INTERVAL '0.000001' SECOND),TO_DATE('31-DEC-9999', 'DD-MON-YYYY')) AS END_DATE,
ba.DELETE_FLAG,
ba.CAMPUS_ID,
ba.LOCATION_ID,
ba.IMAGE_URL,
ba.NAME
FROM
T_BUILDING b
INNER JOIN T_BUILDING_ATTRIBUTE ba
ON b.ID = ba.BUILDING_ID
LEFT JOIN T_BUILDING_ATTRIBUTE ba2
ON ba.BUILDING_ID = ba2.BUILDING_ID
AND ba2.EFFECTIVE_DATE > ba.EFFECTIVE_DATE
GROUP BY
ba.BUILDING_ID,
b.LOCAL_ID,
b.INSTITUTION_ID,
ba.EFFECTIVE_DATE,
ba.DELETE_FLAG,
ba.CAMPUS_ID,
ba.LOCATION_ID,
ba.IMAGE_URL,
ba.NAME
ORDER BY ba.BUILDING_ID, ba.EFFECTIVE_DATE DESC;
更新2:
以下是视图中类型的屏幕截图
CAMPUS_ID - NUMBER(10) LOCATION_ID - NUMBER(10) IMAGE_URL - VARCHAR(500) 名称 - VARCHAR(255) BUILDING_ID - 数量(10) LOCAL_ID - VARCHAR(30) INSTITUTION_ID - NUMBER(10) EFFECTIVE_DATE - TIMESTAMP(6) END_DATE - TIMESTAMP(6) DELETE_FLAG - CHAR(1)
答案 0 :(得分:1)
以下是视图和引用游标返回的列及其数据类型列表:
LIST OF COLS FROM VIEW DATATYPE FROM VIEW LIST OF COLS FROM CURSOR DATATYPE FROM CURSOR
---------------------- ------------------ ------------------------ --------------------
BUILDING_ID NUMBER(10) BUILDING_ID NUMBER(10)
LOCAL_ID VARCHAR(30) CAMPUS_ID NUMBER(10)
INSTITUTION_ID NUMBER(10) DELETE_FLAG CHAR(1)
EFFECTIVE_DATE TIMESTAMP(6) max(EFFECTIVE_DATE) TIMESTAMP(6)
END_DATE TIMESTAMP(6) END_DATE TIMESTAMP(6)
DELETE_FLAG CHAR(1) IMAGE_URL VARCHAR(500)
CAMPUS_ID NUMBER(10) INSTITUTION_ID NUMBER(10)
LOCATION_ID NUMBER(10) LOCAL_ID VARCHAR(30)
IMAGE_URL VARCHAR(500) LOCATION_ID NUMBER(10)
NAME VARCHAR(255) NAME VARCHAR(255)
它们不一样,但是通过在sp_delete_building过程中使用V_BUILDING%ROWTYPE
,您将ref光标结果视为列顺序与视图的顺序相同。
您可以看到视图的数据类型与光标选择列表之间存在多个不匹配 - 可能是“LOCATION_ID / LOCAL_ID”不匹配导致您看到的无效数字错误。
您需要更改引用游标的顺序,以便按照与视图相同的顺序返回列列表,或者在v_building_rec记录类型中显式列出游标列。
顺便说一句,您应该在refcursor中为max(EFFECTIVE_DATE)
列添加别名。