2012-10-19 267 views
3

我正在編寫一個Oracle存儲過程以返回數據庫查詢的結果。如果查詢不產生任何結果,則必須運行第二個查詢。Oracle DB:如果第一個查詢爲空,則返回第二個查詢

在SQL Server中,我能做到這一點使用的東西類似以下內容:

INSERT INTO @TableVar 
SELECT <joinQuery1>; 

IF (SELECT COUNT(*) FROM @TableVar) > 0 
BEGIN 
    SELECT * FROM @TableVar; -- returns <joinQuery1> 
END 
ELSE 
    SELECT <joinQuery2>; --returns <joinQuery2> 
END 

不過,我不能換我圍​​繞如何完成相同的任務在Oracle中的頭。

+0

或者說,我不能找到一個辦法做到這一點不違反幹。即(選擇)聯盟所有(選擇哪裏選擇計數()= 0)應該工作,但我會用它作爲最後的手段。 –

回答

6

你可以利用,使這個更好的表現(和更容易維護):

WITH query1 as (
    select 1, 2 
    from dual 
    where 1=0 
    connect by level <= 10 
), 
query2 as (
    select 3, 4 
    from dual 
    connect by level <= 10 
) 
select * 
from query1 
union all 
select * 
from query2 
where not exists (
    select null 
    from query1 
); 

正如這應該從QUERY2返回10行。如果從query1中刪除where 1 = 0(導致它實際返回行),則應該從query1中獲得10行。

+0

美麗!維護和性能(按照該順序)正是我在做「重新查詢」時所擔心的兩個問題,但這樣做以非常乾淨的方式解決了它們。謝謝! –

0

答案很大程度上取決於你如何進一步使用查詢結果。所以你應該使用pipelened函數,插入GTT或返回ref cursor。

無論如何,我會建議你在1個SQL語句中做到這一點,以實現讀一致性。

所以請考慮像

create procedure test (pCursor out sys_refcursor) is 
begin 
open pCursor for 
select <joinQuery1> 
union all 
SELECT <joinQuery2> 
where not exists (select 1 from joinquery1) 
; 
end; 
+0

這也是我最初的想法,但從維修角度來看,我必須在兩個地方管理。上面提到的WITH條款Craig對此非常好。 –

相關問題