DBMS_OUTPUT 未使用游标获取输出中的任何行
Posted
技术标签:
【中文标题】DBMS_OUTPUT 未使用游标获取输出中的任何行【英文标题】:DBMS_OUTPUT not fetching any rows in output using cursor 【发布时间】:2019-04-25 07:10:10 【问题描述】:DBMS_OUTPUT.PUT_LINE
在使用光标时没有返回数据,如下代码所示
我使用布尔值来比较表中的金额
SET SERVEROUTPUT ON;
DECLARE
--declaration of variable
x_id test.saa.id%TYPE;
x_acctname test.saa.acctname%TYPE;
x_curbal test.saa.balamt%TYPE;
x_sid test.saa.sid%TYPE;
--setting of the boolean value default to null
b_lowamount BOOLEAN := false;
--declaration of cursor
CURSOR custbal IS
SELECT id,acctname,bal_amt,sid
FROM
test.saa WHERE ROWNUM <= 1000;
BEGIN
--checking cursor is open or not
IF NOT ( custbal%isopen ) THEN
OPEN custbal;
END IF;
LOOP
FETCH custbal INTO
x_id,
x_acctname,
x_curbal,
x_sid;
EXIT WHEN custbal%notfound;
CONTINUE WHEN custbal%found;
--begin another
BEGIN
b_lowamount := ( x_curbal < 10 );
IF b_lowamount THEN
dbms_output.put_line('The customer having '|| x_acctname|| ' with sol_id '|| x_sid|| 'with balance RS. '|| x_curbal);
ELSE
dbms_output.put_line('The customer having '|| x_acctname|| ' with sol_id '|| x_sid|| 'with balance RS. '|| x_curbal);
END IF;
END;
END loop;
end;
虽然程序成功完成,但没有返回任何内容
【问题讨论】:
【参考方案1】:没有显示您的输出的原因是因为CONTINUE
- 这意味着转到下一个循环的开始。
相反,您的程序可以写成:
DECLARE
--declaration of variable
x_id test.saa.id%TYPE;
x_acctname test.saa.acctname%TYPE;
x_curbal test.saa.balamt%TYPE;
x_sid test.saa.sid%TYPE;
--setting of the boolean value default to null
b_lowamount BOOLEAN := FALSE;
--declaration of cursor
CURSOR custbal IS
SELECT id,
acctname,
bal_amt,
sid
FROM test.saa
WHERE rownum <= 1000;
BEGIN
OPEN custbal;
LOOP
FETCH custbal
INTO x_id,
x_acctname,
x_curbal,
x_sid;
EXIT WHEN custbal%NOTFOUND;
b_lowamount := (x_curbal < 10);
IF b_lowamount
THEN
dbms_output.put_line('The customer having ' || x_acctname || ' with sol_id ' || x_sid || 'with balance RS. ' || x_curbal);
ELSE
dbms_output.put_line('The customer having ' || x_acctname || ' with sol_id ' || x_sid || 'with balance RS. ' || x_curbal);
END IF;
END LOOP;
CLOSE custbal;
END;
/
注意我已经删除了循环中多余的BEGIN
和END
;无需在当前区块内开始新区块!
另外,我已经删除了您对游标是否打开的检查(它将始终在匿名块的开头关闭,因为游标完全在匿名块的范围内声明,并且 Oracle 关闭范围结束后的变量。但是,我添加了一个显式的CLOSE
语句来关闭游标。这不是严格需要的(因为一旦块完成,游标将自动关闭),但这是一个好习惯如果您手动打开光标,则将其包含在内。
但是,您的整个过程可以简化为:
BEGIN
FOR rec IN (SELECT id,
acctname,
bal_amt,
sid
FROM test.saa
WHERE rownum <= 1000)
LOOP
IF rec.bal_amt < 10
THEN
dbms_output.put_line('The customer having ' || rec.acctname || ' with sol_id ' || rec.sid || 'with balance RS. ' || rec.curbal);
ELSE
dbms_output.put_line('The customer having ' || rec.acctname || ' with sol_id ' || rec.sid || 'with balance RS. ' || rec.curbal);
END IF;
END LOOP;
END;
/
(我保留了 IF
语句原样,即使两个分支都输出相同的字符串 - 我认为这是一个错误,并且您的意思是要输出不同的文本,具体取决于余额小于 10还是不要?如果没关系,你可以去掉IF
语句,直接输出结果。)
游标 for 循环的好处是你不需要声明变量来返回值(记录是作为FOR <record> in (<cursor>)
语句的一部分隐式创建的),你不需要处理光标的打开和关闭。它还使您的代码更简单,因此 - IMO - 更易于理解和维护。
【讨论】:
谢谢在删除 EXIT WHEN 条件后它起作用了 但它在 dbms_output 的所有行中返回了相同的表记录。Alternative way is working Properly
.
到底为什么要删除 exit when 子句?这意味着你会进入一个无限循环!
这样做之后我进入了无限循环,但 dbms_output 的所有记录都返回相同
这不足为奇;如果您没有获取行但由于没有 n 退出条件而仍在循环,则在获取最后一行后变量中的值不会改变。总之,把exit when子句放回去!!!
伟人!以上是关于DBMS_OUTPUT 未使用游标获取输出中的任何行的主要内容,如果未能解决你的问题,请参考以下文章