在运行存储过程以获取某些行时,首先,我想在发送结果之前验证查询是否将返回一行,其次,如果无需两次运行相同的查询就可以进行验证。

我正在使用游标存储产生的结果,因此我尝试了游标属性%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 删除检查和游标第二次打开之间的某行时,您将如何处理?

最后考虑返回异常而不是返回代码。

10-08 13:31
查看更多