在NVL函数中使用选择语句

7
我将尝试运行以下查询:
select a.*, 
    case when NVL (SELECT max(b.field1)
        FROM b
        where b.field2 = a.tbl_a_PK , 'TRUE') = 'TRUE' 
            then 'has no data in b'
            else 'has data in b' end as b_status
from a

我检查了nvl内部的select语句,发现它仅返回1个值(因此不应该有问题)。然而,我收到了“ORA-00936: missing expression”错误提示。


刚刚我意识到我可以同样轻松地做到这一点:选择a.*,当(SELECT max(b.field1) FROM b WHERE b.field2 = a.tbl_a_PK)为空时,则为“在b中没有数据”,否则为“在b中有数据”的情况。但我仍然好奇nvl出了什么问题。 - Naama Zrihen
你需要在函数内部使用括号包裹select语句。使用Coalesce()比Nvl()更好的实践。 - David Aldridge
3个回答

7

NVL()需要两个参数:要测试的表达式和默认值,例如nvl(some_field, 111)。您只需要通过大括号隔离查询参数并提供第二个参数,就像在这个语句中一样:

select nvl( (select 1 from dual), 34) from dual 

在你的变量解析器中,期望在SELECT关键字后面有逗号,否则无法解析剩余字符串。

确切地说,你的语句应该像这样:

select 
  a.*, 
  case when NVL(
              ( SELECT max(b.field1)
                FROM b
                where b.field2 = a.tbl_a_PK
              ), 
              'TRUE'
            ) = 'TRUE' 
       then 'has no data in b'
       else 'has data in b' end                  as b_status
from a

希望这能帮到您...
更新: 在性能方面,最好使用“exists”而不是“max”:
select 
  a.*, 
  case when exists
              ( SELECT null
                FROM b
                where b.field2 = a.tbl_a_PK 
                      and 
                      b.field2 is not null
                      and 
                      rownum = 1
              ), 
       then 'has data in b'
       else 'has no data in b' end                  as b_status
from a

1

如果您正在搜索一个在b中具有/不具有关联记录的a中的记录

select a.*, 
       case when b.field2 is null then 'has no data in b'
                                  else 'has data in b'
        as b_status
from a left outer join b
on a.tbl_a_PK = b.field2;

应该这样做。

1

NVL(string1, replace_with)函数需要两个参数,相关文档请参阅: http://www.techonthenet.com/oracle/functions/nvl.php
Ora 10g文档:http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions105.htm
由于您已经了解问题,此查询可以解决它:

select a.*,
       case
         when (SELECT NVL(b.field2, 0) FROM b where b.field2 = a.tbl_a_PK and rownum = 1) > 0 then
          'has data in b'
         else
          'has no data in b'
       end b_status
  from a

并且运行速度更快。
您不需要使用max()来检查值是否存在于另一个表中,只需检查主键是否不为空即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接