我有一个程序,其结构如下:
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条记录。
答案 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;
/
结果:未找到