如果查询没有返回任何内容,我试图在结果集中获取一些默认值。我正在尝试使用nvl
,但它没有返回预期的默认值。要模拟,请考虑以下查询,
select nvl(null, '10') from dual where 1=0;
如果给定条件不成立,我想获得10
并且查询不返回任何值。但是上面的查询没有返回任何行。
答案 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()
也适用于此。