2013-05-01 205 views
0

我在使用WHERE子句時遇到了一些問題(使用SQL 2008)。我必須創建一個存儲過程,它返回基於7個參數的結果列表,其中一些參數可能爲null。有問題的是@elements,@categories和@edu_id。它們可以是ID列表,也可以是空的。如果參數不爲空,你可以在我的where子句中看到我的特定代碼有效。我不知道如何編碼SQL,如果他們爲空。數據庫中的字段爲INT。SQL WHERE ... IN子句中可能爲null參數

我希望我的問題很清楚。下面是我的查詢。

BEGIN 
DECLARE @elements nvarchar(30) 
DECLARE @jobtype_id INT 
DECLARE @edu_id nvarchar(30) 
DECLARE @categories nvarchar(30) 
DECLARE @full_part bit 
DECLARE @in_demand bit 
DECLARE @lang char(2) 

SET @jobtype_id = null 
SET @lang = 'en' 
SET @full_part = null -- full = 1, part = 0 
SET @elements = '1,2,3' 
SET @categories = '1,2,3' 
SET @edu_id = '3,4,5' 

select 
jobs.name_en, 
parttime.fulltime_only, 
jc.cat_id category, 
je.element_id elem, 
jt.name_en jobtype, 
jobs.edu_id minEdu, 
education.name_en edu 
from jobs 
left join job_categories jc 
on (jobs.job_id = jc.job_id) 
left join job_elements je 
on (jobs.job_id = je.job_id) 
left join job_type jt 
on (jobs.jobtype_id = jt.jobtype_id) 
left join education 
on (jobs.edu_id = education.edu_id) 
left join 
(select job_id, case when (jobs.parttime_en IS NULL OR jobs.parttime_en = '') then 1 else 0 end fulltime_only from jobs) as parttime 
on jobs.job_id = parttime.job_id 
where [disabled] = 0  
and jobs.jobtype_id = isnull(@jobtype_id,jobs.jobtype_id) 
and fulltime_only = isnull(@full_part,fulltime_only) 
-- each of the following clauses should be validated to see if the parameter is null 
-- if it is, the clause should not be used, or the SELECT * FROM ListToInt... should be replaced by 
-- the field evaluated: ie if @elements is null, je.element_id in (je.element_id) 
and je.element_id IN (SELECT * FROM ListToInt(@elements,',')) 
and jc.cat_id IN (SELECT * FROM ListToInt(@categories,',')) 
and education.edu_id IN (SELECT * FROM ListToInt(@edu_id,',')) 

order by case when @lang='fr' then jobs.name_fr else jobs.name_en end; 

END 
+0

'WHERE .. @X IS NULL或@X = COL ..' - 查詢規劃器將全部排序。 – user2246674 2013-05-01 18:21:43

+0

@ user2246674 - 沒有'OPTION(RECOMPILE)'它沒有(性能明智) – 2013-05-01 18:23:26

+0

@MartinSmith啊,是的,一個好點 - 可以影響計劃和改變使用的連接。但是這些常量是不是還沒有重新編譯就摺疊了? – user2246674 2013-05-01 18:25:03

回答

2

and (@elements IS NULL OR je.element_id IN 
(SELECT * FROM ListToInt(@elements,','))) 
and (@categories IS NULL OR 
jc.cat_id IN (SELECT * FROM ListToInt(@categories,','))) 
.... 

的東西應該做的伎倆

0
je.element_id IN (SELECT * FROM ListToInt(@elements,',')) OR @elements IS NULL 

這種方式爲每一個

0

您是否嘗試過比較明確地爲NULL?

and (@elements is null or je.element_id IN (SELECT * FROM ListToInt(@elements,',')) 

依此類推。