Error "Error de conversión" con la expresión ORDER BY CASE

10

Tengo el siguiente Procedimiento almacenado que funciona muy bien, EXCEPTO cuando configuro 'OrderBy' en 'OrderNumber'.

Recibo el siguiente error: Error de conversión al convertir el valor nvarchar 'SK11270' al tipo de datos int.

(SK11270 es un valor en la columna OrderNumber que es nvarchar (50))

Si ejecuto la consulta idéntica con cualquier otra columna OrderBy, funciona bien.

Estoy completamente perdido y me duele la cabeza. ¿Alguien puede ver algo obvio que pueda estar causando este problema?

Gracias de antemano por cualquier idea ...

Rico

Esto funciona:

sp_jobs '1','20','','JobNumber','ASC','97','True','True','True','True','True','True','True','True','True','False','True','False','True','False','0'

Esto no:
sp_jobs '1','20','','OrderNumber','ASC','97','True','True','True','True','True','True','True','True','True','False','True','False','True','False','0'

PROCEDURE [dbo].[sp_Jobs] 

@PageNumber int,
@PageSize int,
@FilterExpression varchar(500),
@OrderBy varchar(50),
@OrderDirection varchar(50),
@CustomerID int,
@ShowNotSet bit,
@ShowPlaced bit,
@ShowProofed bit,
@ShowReProofed bit,
@ShowApproved bit,
@ShowOnTime bit,
@ShowLate bit,
@ShowProblem bit,
@ShowCompleted bit,
@ShowDispatched bit,
@ShowUnapproved bit,
@ShowClosed bit,
@ShowReturned bit,
@ShowNoStock bit,
@UserID int

WITH RECOMPILE 

AS

BEGIN
WITH    Keys 
AS (SELECT TOP (@PageNumber * @PageSize) ROW_NUMBER() OVER (
        ORDER BY
            CASE WHEN @OrderDirection = 'ASC' THEN
                CASE 
                  WHEN @OrderBy = 'JobNumber' THEN p1.JobNumber
                  WHEN @OrderBy = 'OrderNumber' THEN p1.OrderNumber 
                  WHEN @OrderBy = 'CustID' THEN p1.CustID
                  WHEN @OrderBy = 'Status' THEN p1.MasterJobStatusID  
                  WHEN @OrderBy = 'DateIn' THEN p1.DateIn
                  WHEN @OrderBy = 'DateDue' THEN p1.DateDue
                  WHEN @OrderBy = 'DateOut' THEN p1.DateOut 
                 ELSE NULL 
                END
            END ASC
            , CASE WHEN @OrderDirection = 'DESC' THEN
                CASE 
                  WHEN @OrderBy = 'JobNumber' THEN p1.JobNumber
                  WHEN @OrderBy = 'OrderNumber' THEN p1.OrderNumber 
                  WHEN @OrderBy = 'CustID' THEN p1.CustID
                  WHEN @OrderBy = 'Status' THEN p1.MasterJobStatusID  
                  WHEN @OrderBy = 'DateIn' THEN p1.DateIn
                  WHEN @OrderBy = 'DateDue' THEN p1.DateDue
                  WHEN @OrderBy = 'DateOut' THEN p1.DateOut           
                 ELSE NULL 
                END
            END DESC)  as rn ,P1.jobNumber,P1.CustID,P1.DateIn,P1.DateDue,P1.DateOut,p1.client,p1.MasterJobStatusID,p1.MasterJobStatusTimestamp,p1.OwnerID,p1.StockComplete,p1.OrderNumber
        FROM vw_Jobs_List P1  WITH (NOLOCK) 
        WHERE (@CustomerID = 0 OR CustID = @CustomerID) AND  (@UserID = 0 OR OwnerID = @UserID) AND ((@ShowNotSet = 1 AND MasterJobStatusID=1) OR (@ShowPlaced = 1 AND MasterJobStatusID=2) OR (@ShowProofed = 1 AND MasterJobStatusID=3)  OR (@ShowReProofed = 1 AND MasterJobStatusID=4)  OR
         (@ShowApproved = 1 AND MasterJobStatusID=5)  OR (@ShowOnTime = 1 AND MasterJobStatusID=6)  OR (@ShowLate = 1 AND MasterJobStatusID=7)  OR (@ShowProblem = 1 AND MasterJobStatusID=8)  OR (@ShowCompleted = 1 AND MasterJobStatusID=9)  OR
         (@ShowDispatched = 1 AND MasterJobStatusID=10) OR (@ShowUnapproved = 1 AND MasterJobStatusID=11)  OR (@ShowClosed = 1 AND MasterJobStatusID=12) OR  (@ShowReturned = 1 AND MasterJobStatusID=13) OR (@ShowNoStock=1 AND StockComplete=0))
         AND (Search LIKE '%'+@FilterExpression+'%')),SelectedKeys

AS  (SELECT TOP (@PageSize)SK.rn,SK.JobNumber,SK.CustID,SK.DateIn,SK.DateDue,SK.DateOut,SK.OrderNumber,SK.MasterJobStatusID
        FROM Keys SK 
        WHERE SK.rn > ((@PageNumber-1) * @PageSize))

        SELECT  SK.rn,J.JobNumber,J.OwnerID,J.Description,J.Client,SK.CustID,SK.OrderNumber, CAST(DateAdd(d, -2, CAST(isnull(SK.DateIn,0) AS DateTime)) AS nvarchar) AS DateIn, CAST(DateAdd(d, -2, CAST(isnull(SK.DateDue,0) AS DateTime)) AS nvarchar) AS DateDue,CAST(DateAdd(d, -2, CAST(isnull(SK.DateOut,0) AS DateTime)) AS nvarchar) AS DateOut, Del_Method,Ticket#, InvoiceEmailed, InvoicePrinted, InvoiceExported, InvoiceComplete, JobStatus,j.MasterJobStatusID,j.MasterJobStatusTimestamp,js.MasterJobStatus,StockComplete
        FROM SelectedKeys SK JOIN vw_Jobs_List J  WITH (NOLOCK)  ON j.JobNumber=SK.JobNumber JOIN tbl_SYSTEM_MasterJobStatus js  WITH (NOLOCK)  ON j.MasterJobStatusID=js.MasterJobStatusID

END
VaticNZ
fuente

Respuestas:

15

Su expresión CASE solo puede tener un tipo de datos. Pero el suyo está mezclando tipos de datos y se está utilizando el más alto (según la precedencia de tipo de datos ). Entonces nvarchar se cambia a int según estas reglas.

Necesita un caso por tipo de datos o por columna

Ejemplo:

CASE WHEN @OrderDirection = 'DESC' THEN
                 CASE 
                  WHEN @OrderBy = 'JobNumber' THEN J.JobNumber
                  WHEN @OrderBy = 'CustID' THEN J.CustID
                  WHEN @OrderBy = 'DateIn' THEN J.DateIn
                  WHEN @OrderBy = 'DateDue' THEN J.DateDue
                  WHEN @OrderBy = 'DateOut' THEN J.DateOut
                  WHEN @OrderBy = 'Status' THEN J.MasterJobStatusID 
                  ELSE NULL
                END
            END DESC,
CASE WHEN @OrderDirection = 'DESC' THEN
                 CASE 
                  WHEN @OrderBy = 'OrderNumber' THEN J.OrderNumber
                  ELSE NULL
                END
            END DESC
gbn
fuente
5

Mi culpa Vatic, debería haber señalado esto en mi respuesta a su pregunta anterior. Cuando se utiliza una expresión CASE en un orden, debe tratar cada tipo de datos en una expresión separada. Lo siguiente no se ha probado, pero debería estar más cerca de lo que necesita.

ORDER BY
    CASE WHEN @OrderDirection = 'ASC' THEN
        CASE @OrderBy -- int
            WHEN 'JobNumber' THEN p1.JobNumber 
            WHEN 'CustID' THEN p1.CustID
            WHEN 'Status' THEN p1.MasterJobStatusID  
        END
    END ASC,
    CASE WHEN @OrderDirection = 'ASC' THEN
        CASE @OrderBy -- datetime
             WHEN 'DateIn' THEN p1.DateIn
             WHEN 'DateDue' THEN p1.DateDue
             WHEN 'DateOut' THEN p1.DateOut  
        END
    END ASC,
    CASE WHEN @OrderDirection = 'ASC' THEN
        CASE @OrderBy -- nvarchar
             WHEN 'OrderNumber' THEN p1.OrderNumber  
        END
    END ASC,
    CASE WHEN @OrderDirection = 'DESC' THEN
        CASE @OrderBy -- int
            WHEN 'JobNumber' THEN p1.JobNumber 
            WHEN 'CustID' THEN p1.CustID
            WHEN 'Status' THEN p1.MasterJobStatusID  
        END
    END DESC,
    CASE WHEN @OrderDirection = 'DESC' THEN
        CASE @OrderBy -- datetime
             WHEN 'DateIn' THEN p1.DateIn
             WHEN 'DateDue' THEN p1.DateDue
             WHEN 'DateOut' THEN p1.DateOut  
        END
    END DESC,
    CASE WHEN @OrderDirection = 'ASC' THEN
        CASE @OrderBy -- nvarchar
             WHEN 'OrderNumber' THEN p1.OrderNumber  
        END
    END DESC
Mark Storey-Smith
fuente