2013-11-03 4 views
0

에 잘못된 데이터 유형 NVARCHAR 나는 SQL 서버 내 저장 프로 시저에 문제가 2012 년저장 프로 시저 및 숫자

먼저 테이블 :

[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,363,210

절차는 잘 작동하지만.

누군가가이 문제를 해결할 수 있습니까? 답변을 주셔서 감사합니다.

답변

1

사례의 모든 출력 옵션은 동일한 데이터 유형이어야하며, 첫 번째 옵션에서 사용할 출력 유형을 결정하고 다른 값을 해당 유형으로 변환하려고 시도합니다. 귀하의 경우 첫 번째 및 마지막 옵션 (제품 ID 및 가격), 숫자이며, 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로 변환 할 수 있지만 it encounters an error converting data type nvarchar to numeric으로Name실패합니다.

같은 결과를 얻을이 시도 :

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() 기능은 제품 ID 및 가격 열의 숫자와 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 식의 형식은 데이터 형식 우선 순위가 가장 높은 분기의 식입니다. 당신이 마지막으로 OPTION (RECOMPILE)를 사용하는 경우

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 

은 또한 당신이 더 나은 계획을 얻을 수 있습니다 사용할 수 있습니다.