2016-10-04 4 views
1

У меня есть запрос, в котором я должен выполнять фильтрацию с использованием case case. Кажется, каждое условие случай становится выполнено:Ошибка при записи else case case в sql

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 является внутр. Но я сомневаюсь, что если статус statrement не соответствует условию, почему он его выполняет? И решение, как это сделать.


При реализации в запросе ниже получать ту же ошибку скажите мне, где я не прав:

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

is [WeekOfYear] на самом деле int? вы, кажется, сравниваете строку с int - возможно, не с CASE как таковой – Cato

+0

oh, вы знаете, что так или иначе - зачем выставляете сообщение об ошибке, если знаете, что это такое? Почему бы не исправить вашу ошибку и посмотреть, как это происходит? – Cato

ответ

2

проблема, вероятно, выражение case в where. Честно говоря, это проще сделать без case. Я думаю, что это то, что вы хотите:

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

EDIT:

О, это очень интересно. 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

awesome спасибо за помощь –

+0

все еще получаю ту же ошибку –

+0

добавление запроса на верхнюю –