2017-01-20 57 views
2

對不起,如果這是一個愚蠢的問題,我是PL/SQL的新手。 我有一個從表中檢索數據的PL/SQL存儲過程。 有兩個可選參數可以爲空。如果它們不爲空,它們應該成爲WHERE子句的一部分。是否可以在SELECT中的WHERE子句中插入IF子句?

這是SELECT:

SELECT DISTINCT PN.PART_NUMBER, PN.SHORT_CODE, DES.DESCRIPTION 
FROM   MAS_PART    PN 
LEFT JOIN  CF_DESCRIPTION  DES 
ON PN.LOCAL_DESCRIPTION_ID = DES.DESCRIPTION_ID    
WHERE PN.PART_CODE = 'M' 
AND PN.PART_TYPE_ID = IN_PART_TYPE_ID 
AND PN.PART_GROUP_ID = IN_PART_GROUP_ID 
ORDER BY PN.PART_NUMBER; 

的兩個變量是IN_PART_TYPE_IDIN_PART_GROUP_ID。只有當它們不是NULL時,有沒有什麼方法可以評估關於這兩個變量的WHERE子句?或者唯一的方法是使用IF子句重複SELECT 3次並更改WHERE子句?

+2

'其中(col = param或param爲null)和...' – jarlh

回答

4

OR算子將幫助:

SELECT DISTINCT PN.PART_NUMBER, PN.SHORT_CODE, DES.DESCRIPTION 
FROM   MAS_PART    PN 
LEFT JOIN  CF_DESCRIPTION  DES 
ON PN.LOCAL_DESCRIPTION_ID = DES.DESCRIPTION_ID    
WHERE PN.PART_CODE = 'M' 
AND (PN.PART_TYPE_ID = IN_PART_TYPE_ID or IN_PART_TYPE_ID is null) 
AND (PN.PART_GROUP_ID = IN_PART_GROUP_ID or IN_PART_GROUP_ID is null) 
ORDER BY PN.PART_NUMBER; 

另一種選擇是使用NVL:

SELECT DISTINCT PN.PART_NUMBER, PN.SHORT_CODE, DES.DESCRIPTION 
FROM   MAS_PART    PN 
LEFT JOIN  CF_DESCRIPTION  DES 
ON PN.LOCAL_DESCRIPTION_ID = DES.DESCRIPTION_ID    
WHERE PN.PART_CODE = 'M' 
AND PN.PART_TYPE_ID = NVL(IN_PART_TYPE_ID, PN.PART_TYPE_ID) 
AND PN.PART_GROUP_ID = NVL(IN_PART_GROUP_ID, PN.PART_GROUP_ID) 
ORDER BY PN.PART_NUMBER; 

但它只會工作,如果PN.PART_TYPE_ID和PN.PART_GROUP_ID不爲空

+0

您可以將它擴展爲: AND nvl(PN.PART_TYPE_ID,'X#z')= NVL(IN_PART_TYPE_ID,nvl(PN.PART_TYPE_ID,'X #z'))'來覆蓋空值。其中'X#z'是某列不能存在的字符串。 – Kacper

+0

但是如果你在列上有一個索引,它將被認爲是'(column = some_expression)',而不是'(some_function(column)= some_expression)' – vav

+1

使用'NVL'不會給出與首先查詢表中的值是否爲「NULL」。當SELECT NULL CASE WHEN = NULL(NULL,NULL)then SELECT 1 ELSE 0 END FROM DUAL'並將其與'SELECT CASE WHEN(NULL = NULL或NULL IS NULL)然後比較'然後1 ELSE 0 END DUAL'時。 – MT0