如何检查动态光标是否会检索任何记录



我有一个过程,其结构如下:

PROCEDURE broker(prm_qgent in varchar2, prm_cursor out sys_refcursor) 
IS
  mmy_query varchar(200);
BEGIN
  OPEN prm_cursor FOR SELECT * FROM DUAL;
  mmy_query :='SELECT *some dynamic query* where 1=1';
  if prm_agent is not null then
    mmy_query := mmy_query ||'AND agent_code = ''' ||prm_agent || '''';
  end if;
  OPEN prm_cursor FOR mmy_query;
END broker;

mmy_query是搜索标准。因此,如果经纪人不在表格中,则应检索零记录。

mmy_query is要检索记录的动态查询。如果动态查询检索记录,它将仅检索1个记录。因此,我想检查MMY_QUERY是否检索没有记录。

尝试的prm_cursor%ROWTYPE,在两种情况下都显示零记录。尝试的SQL%ROWTYPE,总是显示1个记录。

您需要打开光标,从中获取第一个记录,然后检查找到或未找到的属性。

注意:如果获取第一行,则没有其他方法可以"倒带光标到开始",只是关闭光标并再次打开它(再次执行相同的查询(。<<<<<<<<<<<<<<<<<<<<


根据文档(从上面的链接(,每个命名光标都有4个属性:

%iSopen

name_cursor%iSopen在光标打开时具有true,并且 false如果不打开。

%找到

命名为_cursor%找到以下值之一:

  • 如果光标不打开,Invalid_cursor
  • 如果光标打开,但没有尝试过,请进行null。
  • 如果最新的获取返回了一行,则是。
  • 如果最新的获取未返回一行,false。

%notfound

名称_cursor%notfound具有以下值之一:

  • 如果不打开光标,Invalid_cursor。
  • 如果光标打开,但没有尝试过,请进行null。
  • 如果最近的获取返回了一行,false。
  • 如果最新的获取未返回一行,则是。

%rowcount

名称_cursor%rowcount具有以下值之一:

  • 如果不打开光标,Invalid_cursor。
  • 如果光标打开,则到目前为止获取的行数。

如您所见,没有办法检查查询是没有返回的行还是一行打开光标并从中取出。


简单示例:

返回一些行的查询:

DECLARE
   my_cursor SYS_REFCURSOR;
   y VARCHAR(10);
BEGIN
  OPEN my_cursor FOR 'select * FROM dual WHERE 1=1';
  FETCH my_cursor INTO y;
  IF my_cursor%found THEN
     DBMS_OUTPUT.PUT_LINE('FOUND');
  ELSE
     DBMS_OUTPUT.PUT_LINE('NOT FOUND');
  END IF;
  CLOSE my_cursor;
END;
/

结果:找到


返回空结果集的查询:

DECLARE
   my_cursor SYS_REFCURSOR;
   y VARCHAR(10);
BEGIN
  OPEN my_cursor FOR 'select * FROM dual WHERE 1=0';
  FETCH my_cursor INTO y;
  IF my_cursor%found THEN
     DBMS_OUTPUT.PUT_LINE('FOUND');
  ELSE
     DBMS_OUTPUT.PUT_LINE('NOT FOUND');
  END IF;
  CLOSE my_cursor;
END;
/

结果:找不到

尚不清楚是否会找到行,直到呼叫者试图从光标获取。在打开光标时,这尚未发生。简单地打开并返回光标的过程无法知道呼叫者在完成后尝试从中获取时会发生什么。

也许在理论上可以从v$sql_plan解析执行计划以获取估计的基数,如果您可以找到其sql_id(也许是通过查询v$sql(,但这不是直接的,但最多可以猜测结果是一个猜测。。

您真正能做的就是执行查询两次(如果可能的话,请执行简化版本(,请记住,如果其他会话正在修改数据,则结果可能会在执行之间发生变化。

<</p> <。

最新更新