如何检查 SYS_REFCURSOR 是否为空
how to check if SYS_REFCURSOR is empty
我有一个通用的SYS_REFCURSOR,我想检查它是否为空。
代码是这样的:
declare
v_cursor SYS_REFCURSOR;
begin
OPEN v_cursor FOR <any select statement>.
check if v_cursor is empty.
end;
有人能告诉我如何检查弱游标是否为空吗?
我必须提到基本 SELECT 语句可以是任何 table 中的任何内容。
列号或类型仅在运行时已知。
谢谢,
尝试获取一行然后使用v_cursor%NOTFOUND
确定游标为空:
DECLARE
v_cursor SYS_REFCURSOR;
v_value DUAL.DUMMY%TYPE;
BEGIN
OPEN v_cursor FOR SELECT DUMMY FROM DUAL WHERE 1 = 0;
FETCH v_cursor INTO v_value;
IF v_cursor%NOTFOUND THEN
DBMS_OUTPUT.PUT_LINE('Cursor empty');
ELSE
DBMS_OUTPUT.PUT_LINE('Cursor not empty');
END IF;
END;
/
或
DECLARE
CURSOR v_cursor IS
SELECT DUMMY FROM DUAL WHERE 1 = 0;
v_row v_cursor%ROWTYPE;
BEGIN
OPEN v_cursor;
FETCH v_cursor INTO v_row;
IF v_cursor%NOTFOUND THEN
DBMS_OUTPUT.PUT_LINE('Cursor empty');
ELSE
DBMS_OUTPUT.PUT_LINE('Cursor not empty');
END IF;
END;
/
双输出:
Cursor empty
db<>fiddle here
您无法查看引用游标是否包含数据而不从中提取数据并消耗至少一行。
如果您确实需要在打开游标时确定这一点,而不知道此时的结构,您可以执行修改后的查询,该查询只计算您的真实查询返回的行数 - 可能仅限于单个row if that helps performance - 作为一个简单的 execute immediate ... into ...
或单独的 open/fetch/close 以保持一致性;类似于:
declare
v_cursor SYS_REFCURSOR;
v_query VARCHAR2(4000);
v_count PLS_INTEGER;
begin
v_query := <any select statement>;
-- see if the query finds any data
OPEN v_cursor FOR 'select count(*) from (' || v_query || ')'; -- could limit rows
FETCH v_cursor INTO v_count;
CLOSE v_cursor;
if v_count = 0 then
dbms_output.put_line('No data');
return;
end if;
dbms_output.put_line('Found data, opening cursor for real');
OPEN v_cursor FOR v_query;
-- loop over results, return to caller, etc.
end;
/
我有一个通用的SYS_REFCURSOR,我想检查它是否为空。
代码是这样的:
declare
v_cursor SYS_REFCURSOR;
begin
OPEN v_cursor FOR <any select statement>.
check if v_cursor is empty.
end;
有人能告诉我如何检查弱游标是否为空吗? 我必须提到基本 SELECT 语句可以是任何 table 中的任何内容。 列号或类型仅在运行时已知。
谢谢,
尝试获取一行然后使用v_cursor%NOTFOUND
确定游标为空:
DECLARE
v_cursor SYS_REFCURSOR;
v_value DUAL.DUMMY%TYPE;
BEGIN
OPEN v_cursor FOR SELECT DUMMY FROM DUAL WHERE 1 = 0;
FETCH v_cursor INTO v_value;
IF v_cursor%NOTFOUND THEN
DBMS_OUTPUT.PUT_LINE('Cursor empty');
ELSE
DBMS_OUTPUT.PUT_LINE('Cursor not empty');
END IF;
END;
/
或
DECLARE
CURSOR v_cursor IS
SELECT DUMMY FROM DUAL WHERE 1 = 0;
v_row v_cursor%ROWTYPE;
BEGIN
OPEN v_cursor;
FETCH v_cursor INTO v_row;
IF v_cursor%NOTFOUND THEN
DBMS_OUTPUT.PUT_LINE('Cursor empty');
ELSE
DBMS_OUTPUT.PUT_LINE('Cursor not empty');
END IF;
END;
/
双输出:
Cursor empty
db<>fiddle here
您无法查看引用游标是否包含数据而不从中提取数据并消耗至少一行。
如果您确实需要在打开游标时确定这一点,而不知道此时的结构,您可以执行修改后的查询,该查询只计算您的真实查询返回的行数 - 可能仅限于单个row if that helps performance - 作为一个简单的 execute immediate ... into ...
或单独的 open/fetch/close 以保持一致性;类似于:
declare
v_cursor SYS_REFCURSOR;
v_query VARCHAR2(4000);
v_count PLS_INTEGER;
begin
v_query := <any select statement>;
-- see if the query finds any data
OPEN v_cursor FOR 'select count(*) from (' || v_query || ')'; -- could limit rows
FETCH v_cursor INTO v_count;
CLOSE v_cursor;
if v_count = 0 then
dbms_output.put_line('No data');
return;
end if;
dbms_output.put_line('Found data, opening cursor for real');
OPEN v_cursor FOR v_query;
-- loop over results, return to caller, etc.
end;
/