2012-04-03 6 views
9

Mam dość proste zapytanie stronicowania używany, aby uzyskać wierszy z tabeliKonwersja nie powiodła się, gdy data i/lub czas konwersji z postaci napisu

ALTER PROCEDURE mytable.[news_editor_paginate] 
    @count int, 
    @start int, 
    @orderby int 
AS 
BEGIN 
    SET NOCOUNT ON; 
    SELECT TOP (@count) * FROM 
    ( 
     SELECT news_edits.*, 
     ROW_NUMBER() OVER (
      ORDER BY CASE 
       WHEN @orderby = 0 THEN news_edits.[time] 
       WHEN @orderby = 1 THEN news_edits.lastedit 
       WHEN @orderby = 2 THEN news_edits.title 
       END 
      DESC 
     ) AS num 
     FROM news_edits 
    ) AS a 
    WHERE num > @start 
END 

Parametr @orderby decyduje, która kolumna wyniki powinny być zamawiane przez.

news_edit.[time] i news_edits.lastedit są polami datetime. Ale news_edits.title jest polem varchar.

Kwerenda działa dobrze dla obu pól datetime ale kiedy @orderby = 2 pojawia się następujący błąd:

„Konwersja nie powiodła się podczas konwersji daty i/lub czasu z ciągu znaków”.

Problem w tym, że nie próbuję niczego przekonwertować?

Odpowiedz

19

You'll need to divide your ORDER BY into multiple CASE statements:

ORDER BY 
    CASE WHEN @orderby = 0 THEN news_edits.[time] END DESC, 
    CASE WHEN @orderby = 1 THEN news_edits.lastedit END DESC, 
    CASE WHEN @orderby = 2 THEN news_edits.title END DESC 

To dlatego, że pojedynczy CASE stwierdzenie wymaga, aby wszystkie oddziały mają zgodne typy danych. Ponieważ Twój ciąg znaków w jednym CASE nie może zostać przekonwertowany na czas daty zwrócony z innego CASE, pojawi się błąd konwersji.

+0

To wszystko dziękuję! –

0

Ponieważ nie przesyłasz jednoznacznie wartości "sortuj według wielkości ...", SQL Server podaje, że jest datetime (w zależności od typu pierwszego przypadku).

Rozwiązaniem problemu jest przesłanie dat w formacie ciągu znaków, który pozwala na zamówienie według niego, w rodzaju "rrrrMMddhmmmm". Jeśli to zrobisz, wszystkie wartości "order by case ..." będą znakami i będą działać.

Alternatywnie możesz mieć dwa zaznaczenia i wybrać jeden z nich za pomocą polecenia if. Pierwsza część jeśli dla dat, druga dla tytułu.

Powiązane problemy