在运行存储过程以获取某些行时,首先,我想在发送结果之前验证查询是否将返回一行,其次,如果无需两次运行相同的查询就可以进行验证。
我正在使用游标存储产生的结果,因此我尝试了游标属性%ROWCOUNT
和%NOTFOUND
。但是,不是很有效。另外,我想执行此操作而不在游标上运行循环。
procedure MODULE_LIST_GK(p_module_Id IN MODULE_LIST.MODULE_ID% TYPE,
p_Error_Code out nvarchar2,
p_Error_Msg out nvarchar2,
p_Cursor out sys_refcursor) IS
BEGIN
OPEN p_Cursor FOR
SELECT A.MODULE_ID,
A.MODULE_NM,
A.AUTH_STATUS_ID
FROM MODULE_LIST A
WHERE A.MODULE_ID=p_module_Id;
SELECT COUNT(MODULE_ID)
INTO v_row_num
FROM MODULE_LIST A
WHERE A.MODULE_ID=p_module_Id;
IF v_row_num=0 THEN
p_Error_Code := SQLCODE;
p_Error_Msg := 'Does not Exists';
Return;
end IF;
EXCEPTION
WHEN OTHERS THEN
p_error_code:= SQLCODE;
p_error_msg := SQLERRM;
END MODULE_LIST_GK;
最佳答案
您的实现有几点可以改进。
如果您希望对于很多参数返回的光标为空,则为第一个,
比先检查空的游标,只有在此检查之后才打开游标。反之亦然。
如何检查光标是否为空?不幸的是,您必须获取第一行才能进行验证。
open l_cur for
select id, status from tab where id = p_id;
fetch l_cur into l_id, l_status;
if l_cur%NOTFOUND then
p_Error_Msg := 'Does not Exists';
Return;
end if;
与通常使用的
count(*)
相比,此检查要有效得多,因为它仅考虑前几行,而不考虑游标中所有行的。如果检查失败,则准备就绪,否则,请简单打开游标并返回它。
open l_cur for
select id, status from tab where id = p_id;
p_Cursor := l_cur;
我想到了另外两个想法。
如果数据库是非常动态的,则应该重新采用通用方法。当其他 session 删除检查和游标第二次打开之间的某行时,您将如何处理?
最后考虑返回异常而不是返回代码。