如何检测fetch游标是否返回没有值?

时间:2015-01-22 10:22:15

标签: oracle if-statement cursor

我有这个:

declare
  toStoreA varchar2(10);
  toStoreB varchar2(10);
  toStoreC varchar2(10);

  cursor c1 is
    select a, b, c
    from table1
    where login = 'myLogin';
begin
  open  c1;
  fetch c1 into toStoreA,
                toStoreB,
                toStoreC
  close c1;

  if toStoreB = NULL then
    dbms_output.put_line('OK, we are in if, toStoreB is null');
  end if;

  dbms_output.put_line('toStoreA:' || toStoreA || '_');
  dbms_output.put_line('toStoreB:' || toStoreB || '_');
  dbms_output.put_line('toStoreC:' || toStoreC || '_');
end;

我的目标是检测fetch cursor是否没有返回任何值。

如果我在sql窗口中查询我的sql语句,我会得到这个:

> select a, b, c from table1 where login = 'myLogin';
++++++++++++++++++++++++++++++++++++++++++++
+ some val +               +               +
++++++++++++++++++++++++++++++++++++++++++++

这是我在DBMS输出窗口中得到的:

toStoreA:some val_
toStoreB:_ 
toStoreC:_

如您所见,我在DBMS输出中没有得到字符串OK, we are in if, toStoreB is null。为什么?嗯,很明显,如果没有通过。问题是如何正确检查fetch cursor是否返回null值(无值)?

我也试过if toStoreB = '' then,但没有帮助。

1 个答案:

答案 0 :(得分:4)

你不能平等地测试null; null永远不等于(或等于)任何东西,包括它自己。并且空字符串''与null无法区分,因此您也不能使用相等测试。 See the explanation in the documentation。您可以使用the is null operator来解决当前问题:

  if toStoreB is NULL then

通过这种改变你会看到:

anonymous block completed
OK, we are in if, toStoreB is null
toStoreA:some val_
toStoreB:_
toStoreC:_

我最初稍微误解了这个问题,认为你的意思是你想检查fetch是否没有返回任何行,而不是特定的列没有值;所以其余部分并不直接相关。如果您总是期望单行,那么您可以使用select into ...而不是命名游标;但是使用光标,您可以更灵活地测试所获取的内容......

这只会告诉您,如果b不能为空,则抓取功能找不到任何内容;即使你认为现在的情况不是你应该依赖的东西,也不是一般的解决方案。

您可以使用the `%notfound' cursor attribute检查是否有任何内容:

  open  c1;
    fetch c1 into toStoreA,
                  toStoreB,
                  toStoreC;
    if c1%notfound then
      dbms_output.put_line('No row was fetched');
    end if;
  close c1;

请注意,必须在关闭光标之前检查它,通常在获取后直接检查。如果您尝试在close之后检查它,则会出错。一旦检索到所有数据,这通常用于中断取回的循环。

因此,如果更改和修改后的查询都找不到数据,您会看到:

anonymous block completed
No row was fetched
OK, we are in if, toStoreB is null
toStoreA:_
toStoreB:_
toStoreC:_