2016-10-04 66 views
1

我有一个查询,我必须使用case语句进行过滤。这似乎是越来越执行任何情况下条件:在sql中写入else case语句时出错error

declare @filterValue varchar(50)='test' 
    declare @filterCol varchar(50)='DayOfWeekAbr' 

    select * from datetable where 1=1 and (
    case when @filterCol='' then DayOfWeekAbr 
    when @filterCol='' then [WeekOfYear] 
    end = @filterValue 
    OR case when ISNULL(@filterCol,'')='' then 1 
    end =1) 

四处错误:

Msg 245, Level 16, State 1, Line 5 Conversion failed when converting the varchar value 'test' to data type int.

现在的错误是因为列WEEKOFYEAR为int。但是我的疑问是,如果案件统计不符合它执行它的条件?并解决如何做到这一点。


当下面的查询得到同样的错误,告诉我,我错了实现:

SELECT 
       [threat_feed].[Id] 
       , [threat_feed].[Name] 
       , [threat_feed].[Url] 
       , [threat_feed].[RefreshRate] 
       , [threat_feed].[ConfidenceLevel] 
       , [threat_feed].[Severity] 
       , [threat_feed].[Type] 
       , [threat_feed].[Source] 
       , [threat_feed].[Description] 
       , [threat_feed].[Visibility] 
       , [threat_feed].[Integration] 
       , [threat_feed].[IntegrationOptions] 
       , [threat_feed].[CreatedBy] 
       , [threat_feed].[CreatedOn] 
       , [threat_feed].[ModifiedBy] 
       , [threat_feed].[ModifiedOn] 
       , [threat_feed].[IsDeleted] 
       , COUNT(*) OVER() AS [TOTALROWS] 

      FROM [dbo].[ThreatFeed] [threat_feed] 
      WHERE [threat_feed].[IsDeleted] IN (0, @IncludeDeleted) AND (
     (@filterCol = 'Name' and [threat_feed].[Name] = @filterValue) or 
     (@filterCol = 'Source' and [threat_feed].[Source] = @filterValue) or 
     (@filterCol = 'URL' and [threat_feed].[Url] = @filterValue) or 
     (@filterCol = 'RefreshRate' and [threat_feed].[RefreshRate] = @filterValue) or 
     (@filterCol = 'ConfidenceLevel' and [threat_feed].[ConfidenceLevel] = @filterValue) or 
     (@filterCol = 'Severity' and [threat_feed].[Severity] = @filterValue) or 
     (@filterCol = 'Visibility' and [threat_feed].[Visibility] = @filterValue) or 
     (isnull(@filterCol,'')='') 
     ) 

这里confidencelevel,serverity和知名度不为varchar

+1

您的'CASE'语句中的逻辑没有任何意义。 –

+0

是[WeekOfYear]其实是一个int?你似乎正在比较一个字符串到一个int - 可能不会与CASE做这样的 – Cato

+0

哦,你知道吗?无论如何 - 为什么发布错误,如果你知道它是什么?为什么不解决你的错误,并看看它是怎么回事? – Cato

回答

2

的问题可能是case表达在where。说实话,这更简单地完成没有case。我认为这是你想要什么:

where ((@filterCol = 'DayOfWeekAbr' and DayOfWeekAbr = @filterValue) or 
     (@filterCol = 'WeekOfYear' and WeekOfYear = @filterValue) or 
     (@filterCol is null) 
    ) 

编辑:

哦,这是非常有趣的。 SQL(通常)不保证对布尔表达式的懒惰评估。因此,or的双方都可能被评估。 。 。当过滤器值是一个字符串时,这可能会导致问题,但该列需要一个数字。

这里是一个解决方案:

where (case when @filterCol = 'Name' and [threat_feed].[Name] = @filterValue) then 1 
      when @filterCol = 'Source' and [threat_feed].[Source] = @filterValue) 
      then 1 
      . . . 
     end) = 1 

然后,就可以确保所有的字符串列是日期列前。 case中的条款是保证按顺序搜索。

SQL Server 2012+中的另一种可能性是将try_convert()用于非字符串列。如果RefreshRate是整数:

where . . . 
     (@filterCol = 'URL' and [threat_feed].[Url] = @filterValue) or 
     (@filterCol = 'RefreshRate' and [threat_feed].[RefreshRate] = try_convert(int, @filterValue)) or 
+0

真棒感谢您的帮助 –

+0

仍然有相同的错误 –

+0

在顶部添加查询 –