2016-10-04 1 views
1

Ich habe eine Abfrage, in der ich mit case-Anweisung filtern muss. Es scheint, jeder Fall Bedingung ausgeführt zu werden:Fehler beim Schreiben der else case-Anweisung in 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) 

Erste Fehler:

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

Jetzt ist der Fehler, weil Spalte WeekOfYear int ist. Aber mein Zweifel ist, wenn die Fallregulierung nicht der Bedingung entspricht, warum sie ausgeführt wird? Und die Lösung, wie es geht.


Wenn in der Abfrage implementiert mich unter immer gleichen Fehler sagen, wo ich falsch bin:

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

Hier Confidence, serverity und Sichtbarkeit VARCHAR nicht

+1

Die Logik in Ihrer 'CASE' Aussage macht keinen Sinn. –

+0

ist [WeekOfYear] eigentlich ein int? du scheinst eine Zeichenkette mit einem int zu vergleichen - möglicherweise nicht mit CASE als solcher zu tun – Cato

+0

oh, das weißt du doch - warum einen Fehler melden, wenn du weißt, was es ist? Warum nicht Ihren Fehler beheben und sehen, wie es geht? – Cato

Antwort

2

Das Problem ist wahrscheinlich der case Ausdruck in der where. Um ehrlich zu sein, ist dies ohne die case einfacher. Ich denke, das ist das, was Sie wollen:

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

EDIT:

Oh, das ist sehr interessant. SQL (im Allgemeinen) garantiert keine langsame Auswertung boolescher Ausdrücke. So könnten beide Seiten der or ausgewertet werden. . . Dies kann zu einem Problem führen, wenn der Filterwert eine Zeichenfolge ist, die Spalte jedoch eine Zahl erwartet.

ist hier eine Lösung:

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

Dann, nur sicher sein, dass alle String-Spalten vor den Datumsspalten sind. Die Klauseln in einer casesind garantiert in der Reihenfolge gesucht werden.

Eine andere Möglichkeit in SQL Server 2012+ ist die Verwendung von try_convert() für die Nicht-String-Spalten. wenn RefreshRate SO, eine ganze Zahl:

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

genial danke für Hilfe –

+0

immer noch gleichen Fehler –

+0

Hinzufügen von Abfrage auf der Oberseite –

Verwandte Themen