【问题标题】:SQL WHERE ... IN clause with possibly null parameterSQL WHERE ... IN 子句可能为空参数
【发布时间】:2013-05-01 18:18:05
【问题描述】:

我的 WHERE 子句(使用 SQL 2008)有一些问题。我必须创建一个存储过程,它根据 7 个参数返回结果列表,其中一些参数可能为空。有问题的是@elements、@categories 和@edu_id。它们可以是 id 列表,也可以为 null。您可以在我的 where 子句中看到,如果参数不为空,我的特定代码可以工作。如果它们为空,我不确定如何对 sql 进行编码。这些字段在数据库中是 INT。

我希望我的问题足够清楚。下面是我的查询。

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

【问题讨论】:

  • WHERE .. @X IS NULL OR @X = COL .. - 查询规划器会将其全部整理出来。
  • @user2246674 - 不是没有OPTION (RECOMPILE) 它不会(性能方面)
  • @MartinSmith 啊,是的,这是一个很好的观点 - 这会影响计划并更改使用的连接。但是如果不重新编译,常量不会被折叠吗?
  • @user2246674 - 关于该主题的权威文章是Dynamic Search Conditions in T-SQL Version for SQL 2008

标签: sql where-clause conditional-statements


【解决方案1】:

有点像

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,',')))
....

应该做的伎俩

【讨论】:

    【解决方案2】:
    je.element_id IN (SELECT * FROM ListToInt(@elements,',')) OR @elements IS NULL
    

    每个人都这样

    【讨论】:

      【解决方案3】:

      您是否尝试过明确地与 NULL 进行比较?

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

      等等。

      【讨论】:

        猜你喜欢
        • 2016-10-09
        • 1970-01-01
        • 2011-03-28
        • 2021-02-13
        • 2010-09-25
        相关资源
        最近更新 更多