2013-11-03 37 views
0

我在SQL Server中有我的存儲過程中的問題2012存儲過程和壞的數據類型爲nvarchar到數字

首先表:

[ProductId] [int] IDENTITY(1,1) NOT NULL, 
    [Name] [nvarchar](100) NOT NULL, 
    [Description] [nvarchar](500) NOT NULL, 
    [Category] [nvarchar](50) NOT NULL, 
    [Price] [decimal](16, 2) NOT NULL, 

和存儲過程:

CREATE procedure [dbo].[GetProductsPaging] 
    (@PageOffset bigint=0, 
    @PageSize bigint=5, 
    @OrderBy varchar(30) = 'ProductId', 
    @DescOrder bit = 0) 
    AS 
BEGIN 
    IF @DescOrder = 0 
    BEGIN 
     SELECT * FROM [dbo].Products 
     ORDER BY 
      CASE @OrderBy 
       WHEN 'ProductId' THEN ProductId 
       WHEN 'Name' THEN Name 
       WHEN 'Category' THEN Category 
       WHEN 'Price' THEN Price 
       ELSE NULL 
      END ASC 
     OFFSET @PageOffset ROWS 
     FETCH NEXT @PageSize ROWS ONLY 
    END 
    ELSE 
    BEGIN 
     SELECT * FROM [dbo].Products 
     ORDER BY 
      CASE @OrderBy 
       WHEN 'ProductId' THEN ProductId 
       WHEN 'Name' THEN Name 
       WHEN 'Category' THEN Category 
       WHEN 'Price' THEN Price 
       ELSE NULL 
      END DESC 
     OFFSET @PageOffset ROWS 
     FETCH NEXT @PageSize ROWS ONLY 
    END 
END 

當我這樣執行它時

EXEC dbo.GetProductsPaging 0, 0 ,'Price', 0 

過程時使用此

EXEC dbo.GetProcedurePaging 0, 0, 'Name', 0 

我得到這個錯誤

錯誤轉換數據類型爲nvarchar到數字工作得很好,但。

有人能幫助我嗎?感謝任何答案。

回答

1

從的情況下所有的輸出選項必須是相同的數據類型的,我認爲情況決定什麼輸出類型,從第一個選項使用,並且嘗試其他的值轉換爲這種類型,在你的情況下,第一和最後選項,(產品編號和價格),是數字,BUIT其他都是字符...修改(在兩個地方)的情況如下:

CASE @OrderBy 
    WHEN 'ProductId' THEN str(ProductId, 7, 0) 
    WHEN 'Name' THEN Name 
    WHEN 'Category' THEN Category 
    WHEN 'Price' THEN str(Price, 16,4) 
    ELSE NULL 
END ASC 

然而意識到,任何對價格排序現在將完成性格的基礎上,即100會前20

+0

謝謝你現在的工作。 – Zabaa

+0

我測試價格排序,它仍然排序正確,100後20 – Zabaa

1

我想,那是因爲你CASE表達。你的情況下第一行是WHEN 'ProductId' THEN ProductId,因此它是所有其他字段轉換爲相同的數據類型爲ProductId。它作品Price的價格可以被轉換爲INT但失敗了Nameit encounters an error converting data type nvarchar to numeric

嘗試使用此方法得到相同的結果:

CASE @OrderBy 
     WHEN 'ProductId' THEN RIGHT(100000000 + ProductId, 8) 
     WHEN 'Name' THEN Name 
     WHEN 'Category' THEN Category 
     WHEN 'Price' THEN RIGHT(100000000 + Price, 8) 
     ELSE NULL 
    END ASC 

Right()功能是用來爲你的產品編號和價格列的數字和VARCHAR值相同的順序。請對Order by DESC部分應用相同的更改。

+1

謝謝你,你的解決方案是正確的太 – Zabaa

1
ORDER BY 
     CASE @OrderBy 
      WHEN 'ProductId' THEN ProductId 
      WHEN 'Name' THEN Name 
      WHEN 'Category' THEN Category 
      WHEN 'Price' THEN Price 
      ELSE NULL 
     END ASC 

在混合數字和非數字分支時不起作用。 CASE表達式的類型是具有最高數據類型優先級的分支。您可以使用

ORDER BY 
     CASE @OrderBy 
      WHEN 'ProductId' THEN ProductId 
      WHEN 'Name' THEN Name 
      WHEN 'Category' THEN Category 
      WHEN 'Price' THEN Price 
      ELSE CAST(NULL AS SQL_VARIANT) 
     END ASC 

ORDER BY CASE 
      WHEN 'ProductId' = @OrderBy THEN ProductId 
      END, 
      CASE 
      WHEN 'Name' = @OrderBy THEN Name 
      END, 
      CASE 
      WHEN 'Category' = @OrderBy THEN Category 
      END, 
      CASE 
      WHEN 'Price' = @OrderBy THEN Price 
      END 

而且你可能會得到一個更好的計劃,如果你使用OPTION (RECOMPILE)利用這最後一個。

相關問題