2015-09-25 124 views
3

這個問題關於PLSQL - 用於提高代碼和編碼標準的效率。PLSQL - 提高代碼效率

任何幫助,指針,參考或建議,高度讚賞。

問題:

我有一個輸入參數i_flagBOOLEAN類型的PLSQL過程。

基於這個i_flag的值(可以是true或false),我必須執行一個sql查詢。如果值爲TRUE,則SQL1(假設查詢爲1.1)否則如果值爲FALSE則SQL2(假設查詢爲1.2)將被執行。

SQL2與SQL1相同,只是增加了where子句。

SQL1(1.1)

select a.user_id, a.user_name, a.dept_id, b.country from user a , contact b 
where a.user_id = b.user_id; 

SQL1(1.2)

select a.user_id, a.user_name, a.dept_id, b.country from user a , contact b 
where a.user_id = b.user_id 
and a.user_status is not null; 

,而不是編寫IF-ELSE在PLSQL是有可能寫在一個SQL查詢此查詢的?

+2

'它可以是真或假'是的,這通常是布爾如何工作;) –

+1

@JuanCarlosOropeza當然也可以爲null。這將是一種憎惡,但... –

+0

'i_flag'聽起來不像最自我記錄的參數名稱。 –

回答

3

您可以在一個查詢中使用邏輯or運營商創建相同的行爲:

select a.user_id, a.user_name, a.dept_id, b.country 
from user a , contact b 
where a.user_id = b.user_id AND (i_flag = TRUE OR a.user_status IS NOT NULL) 

注意,順便說一下,隱式連接(具有from子句中的兩個表)是一種過時的語法,和它的建議切換到現代的,明確的,語法:

SELECT a.user_id, a.user_name, a.dept_id, b.country 
FROM user a 
JOIN contact b ON a.user_id = b.user_id 
where i_flag = TRUE OR a.user_status IS NOT NULL 
+6

這不起作用,因爲'boolean'不是有效的SQL數據類型。它只在PL/SQL中有效。您需要將布爾參數轉換爲SQL類型的局部變量,例如「varchar2(1)」,該變量可以是Y或N.然後,您可以在查詢中使用該局部變量。 –

0

首先,如果你想在一個SQL查詢中使用一個布爾值PARAM,你需要替換一個SQL兼容的類型,如NUMBER,即使用0或1代替FALSE或TR UE。其次,儘管Mureinik基於OR的答案將起作用,但如果您使用替代方案,Oracle經常會提供更好的性能。一種替代方案是這樣的:

SELECT a.user_id, a.user_name, a.dept_id, b.country 
FROM user a 
JOIN contact b ON a.user_id = b.user_id 
WHERE 1 = CASE WHEN i_flag = 1 THEN 1 
       WHEN a.user_status IS NOT NULL THEN 1 
       ELSE 0 END 

這不是很漂亮,但在較大的查詢中,它有時會有很大的幫助。

0

語法方面,所有上述答案都很好。 但是,我的兩分錢指的是可能有助於您的表現的不同更改。運行PL/SQL procs時遇到的最大瓶頸是在PL/SQL和SQL引擎(由ORACLE的體系結構分開)之間進行反彈時出現的。因此,經驗法則是最大限度地減少每個程序的個別呼叫數量。

如果我們將此規則應用於您的問題 - 您應該檢查是否可以將refcursor傳遞給過程,該過程包含要查詢的所有用戶及其相應的布爾值。如果現在從批處理用戶的循環內調用該過程,那麼當您擴展到大數時,這樣做將大大有助於提高性能。

0

我認爲寫這個動態sql將是不錯的選擇。

create or replace procedure sp_..(i_flag boolean) 
as 
sql_stmt varchar2(1000):='select a.user_id, a.user_name,'|| 
'a.dept_id,b.country from user a , contact b '|| 
'where a.user_id = b.user_id'; 
begin 
if (i_flag=false) then 
    sql_stmt:=sql_stmt||' and a.user_status is not null'; 
end if; 
---do some stuff with sql_stmt(i.e. refcursor) 
end sp_..; 
+1

IMO無用的使用動態SQL。因人而異。 – user272735

+0

你更喜歡使用dbms_sql @ user272735嗎? –

+0

如果你能舉出你的例子,這將是有益的... –

0

即使我們將能夠實現或條件單查詢中,它可能是不那麼好主意,在性能和動態SQL而言可能是一個更好的選擇。如果你正在尋求提高代碼效率,你可能想看看類似於https://www.youtube.com/watch?v=rWEqO-GpJ4M