如何检查动态游标是否不会检索任何记录?

时间:2018-02-25 09:33:06

标签: oracle plsql dynamic-sql

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

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条记录。

1 个答案:

答案 0 :(得分:0)

您需要打开光标,从中获取第一条记录并检查FOUND or NOT_FOUND attributtes。

注意:如果第一行被提取,则没有其他方法可以将光标重绕到开头#34;除了关闭光标并再次打开它(并再次执行相同的查询)。

根据文档(来自上面的链接),每个命名游标都有4个属性:

  

<强>%ISOPEN

     

如果光标打开,则named_cursor%ISOPEN的值为TRUE,并且   如果没有打开则为FALSE。

     

<强>%FOUND

     

named_cursor%FOUND具有以下值之一:

     
      
  • 如果光标未打开,则为INVALID_CURSOR
  •   
  • 如果游标已打开但未尝试提取,则为NULL。
  •   
  • 如果最近的提取返回一行,则为TRUE。
  •   
  • 如果最近的提取没有返回一行,则为FALSE。
  •   
     

<强>%NOTFOUND

     

named_cursor%NOTFOUND具有以下值之一:

     
      
  • 如果游标未打开,则为INVALID_CURSOR。
  •   
  • 如果游标已打开但未尝试提取,则为NULL。
  •   
  • 如果最近的提取返回一行,则为FALSE。
  •   
  • 如果最近的提取没有返回一行,则为TRUE。
  •   
     

<强>%ROWCOUNT

     

named_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;
/

结果:未找到