2015-06-10 5 views
8

Ich habe eine gespeicherte Prozedur, die durch in Abhängigkeit von einem Parameter eine Bestellung einleitet:ORDER BY abhängig vom Parameter resultiert in Fehler

DROP PROCEDURE [dbo].[GetUsersByClusterAndUserName] 
    GO 
CREATE PROCEDURE [dbo].[GetUsersByClusterAndUserName] 
    @SortField [nvarchar] (256) = 'UserName', 
    @SortOrder [int] = 0 
AS 
    SELECT * FROM [User] 
    ORDER BY 
    CASE WHEN @SortOrder = 0 THEN 
     CASE 
      WHEN @SortField = 'UserName' THEN User_UserName 
      WHEN @SortField = 'LastLoginDate' THEN User_LastLoginDate 
      WHEN @SortField = 'CreationDate' THEN User_CreationDate END 
    END ASC,  
    CASE WHEN @SortOrder = 1 THEN 
     CASE 
      WHEN @SortField = 'UserName' THEN User_UserName 
      WHEN @SortField = 'LastLoginDate' THEN User_LastLoginDate 
      WHEN @SortField = 'CreationDate' THEN [User_CreationDate] END 
    END DESC 
RETURN 0 
GO 

jedoch ... Wenn ich das Verfahren wie folgt aufrufen:

EXEC dbo.GetUsersByClusterAndUserName @SortOrder=1, @SortField='UserName' 

bekomme ich folgende Fehlermeldung:

Msg 241, Level 16, State 1, Procedure GetUsersByClusterAndUserName, Line 7 
Conversion failed when converting date and/or time from character string. 

Warum sollte es versuchen, etwas zu Datum/Zeit zu konvertieren. Kann mir bitte jemand helfen?

+0

Gute Frage! Kleinere Vorschläge, machen Sie den '@ SortOrder' ein' BIT' – Khan

+0

Persönlich würde dies die UI-Kontrolle machen. – UnhandledExcepSean

Antwort

4

Das Problem ist wahrscheinlich Typ Umwandlung von der case. Wenn order by auf diese Weise verwenden, dann mehrere case Anweisungen verwenden:

ORDER BY (CASE WHEN @SortOrder = 0 AND @SortField = 'UserName' THEN User_UserName END), 
     (CASE WHEN @SortOrder = 0 AND @SortField = 'User_LastLoginDate' THEN User_LastLoginDate END), 
     (CASE WHEN @SortOrder = 0 AND @SortField = 'User_CreationDate' THEN User_CreationDate END), 
     (CASE WHEN @SortOrder = 1 AND @SortField = 'UserName' THEN User_UserName END) DESC, 
     (CASE WHEN @SortOrder = 1 AND @SortField = 'User_LastLoginDate' THEN User_LastLoginDate END) DESC, 
     (CASE WHEN @SortOrder = 1 AND @SortField = 'User_CreationDate' THEN User_CreationDate END) DESC 

Das Problem ist, dass die case einen einzelnen Ausgangstyp hat, bestimmt, wenn die Abfrage kompiliert wird. Dieser Typ basiert auf einer Logik, die alle Typen der -Klausel kombiniert. Daher wird das Ergebnis jeder then-Klausel in den Gesamttyp konvertiert - und hier tritt der Fehler auf.

Sie können über Daten Vorrang Regeln here lesen. Aber die Lösung ist einfach: Verwenden Sie mehrere case Anweisungen.

+2

Sie haben ein zusätzliches WHEN (das zweite) in jeder CASE-Anweisung. –

+0

Funktioniert wie ein Charme außer dem zusätzlichen WHEN. Vielen Dank!!! –

Verwandte Themen