2013-11-03 40 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)利用这最后一个。

相关问题