2015-06-10 16 views
8

ho una stored procedure che avvia un ordine da parte dipendente da un parametro:ORDER BY a seconda dei risultati dei parametri per errore

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 

Tuttavia ... Se io chiamo la procedura come questa:

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

ottengo il seguente errore:

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

perché dovrebbe cercare di convertire qualcosa per data/ora. Qualcuno può aiutare, per favore?

+0

Buona domanda! Suggerimenti minori, rendono '@ SortOrder' un' BIT' – Khan

+0

Personalmente, questo è qualcosa che farei il controllo dell'interfaccia utente. – UnhandledExcepSean

risposta

4

Il problema è probabilmente la conversione del tipo da case. Quando si utilizza order by in questo modo, quindi utilizzare più case istruzioni:

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 

Il problema è che il case ha un singolo tipo di uscita, determinato quando la query viene compilata. Questo tipo è basato sulla logica che combina tutti i tipi della clausola THEN. Quindi, il risultato di ciascuna clausola then viene convertito nel tipo generale - ed è qui che si verifica il tuo errore.

È possibile leggere le regole sulla precedenza dei dati here. Ma la soluzione è semplice: usa più istruzioni case.

+2

Hai un WHEN extra (il 2 °) in ogni dichiarazione CASE. –

+0

Funziona come un incantesimo tranne che per l'ulteriore WHEN. Grazie!!! –

Problemi correlati