如果没有返回值,请选择默认值

时间:2017-04-16 14:36:29

标签: oracle null nvl

如果查询没有返回任何内容,我试图在结果集中获取一些默认值。我正在尝试使用nvl,但它没有返回预期的默认值。要模拟,请考虑以下查询,

select nvl(null, '10') from dual where 1=0;

如果给定条件不成立,我想获得10并且查询不返回任何值。但是上面的查询没有返回任何行。

3 个答案:

答案 0 :(得分:2)

您的查询返回零行。 NVL()不会改变(*)

正确的解决方案是执行查询的程序处理NO_DATA_FOUND异常而不是摆弄查询。

但是,您需要一个解决方法,因此这里有一个使用两个子查询,一个用于您的实际查询,一个用于默认查询。

your_query返回空集时,您会得到:

SQL> with your_qry as
  2      ( select col1 from t42 where 1=0 )
  3     , dflt as
  4      ( select 10 as col1 from dual  )
  5  select col1
  6  from your_qry
  7  union all
  8  select col1
  9  from dflt
 10  where not exists (select * from your_qry );

      COL1
----------
        10
SQL> 

当它返回一行时你会得到这个:

SQL> with your_qry as
  2      ( select col1 from t42 )
  3     , dflt as
  4      ( select 10 as col1 from dual  )
  5  select col1
  6  from your_qry
  7  union all
  8  select col1
  9  from dflt
 10  where not exists (select * from your_qry );

      COL1
----------
        12
        13

SQL>

WITH子句在这里是可选的,它只是更容易编写查询而不重复。这将有相同的结果:

select col1
from t42
where col0 is null
union all
select 10
from dual
where not exists (select col1 
                  from t42
                  where col0 is null)
;

(*)好的,有些解决方案使用NVL()COALESCE()进行聚合来执行此操作。当问题出现时,它们在单行中使用单列投影,但是当真实查询具有多个行和/或多个列时,它们会分解。聚合会改变结果。

所以这看起来还不错......

SQL> with cte as (
  2      select 'Z' as col0, 12 as col1 from dual where 1=0 union all
  3     select 'X' as col0, 13 as col1 from dual where 1=0 )
  4  select
  5     nvl(max(col0), 'Y') as col0, nvl(max( col1), 10) as col1
  6  from cte;

COL0             COL1
---------- ----------
Y                  10

SQL> 

......但这不是那么多:

SQL> with cte as (
  2      select 'Z' as col0, 12 as col1 from dual union all
  3     select 'X' as col0, 13 as col1 from dual )
  4  select
  5     nvl(max(col0), 'Y') as col0, nvl(max( col1), 10) as col1
  6  from cte;

COL0             COL1
---------- ----------
Z                  13

SQL>

答案 1 :(得分:0)

这可能是你需要的东西

您可以在两个地方更改WHERE子句(在本例中为WHERE COL > 1)。

WITH T(COL) AS(
    SELECT 1 FROM DUAL UNION ALL
    SELECT 2 FROM DUAL UNION ALL
    SELECT 3 FROM DUAL  
)
 SELECT COL FROM T WHERE COL > 1
 UNION ALL
 SELECT 10  AS COL FROM DUAL WHERE NOT EXISTS( SELECT 1 FROM T WHERE COL > 1)

答案 2 :(得分:-1)

您可以使用聚合。聚合查询始终返回一行:

select coalesce(max(null), '10')
from dual
where 1 = 0;

我更喜欢coalesce()nvl(),因为coalesce()是ANSI标准函数。但是,nvl()也适用于此。