2013-03-09 13 views
7

Mam kilka terminów w varchar tak:Konwersja RRRRMMDD do DATE

20080107 
20090101 
20100405 
... 

Jak przekonwertować je na format daty tak:

2008-01-07 
2009-01-01 
2010-04-05 

Próbowałem za pomocą tego :

SELECT [FIRST_NAME] 
     ,[MIDDLE_NAME] 
     ,[LAST_NAME]  
     ,cast([GRADUATION_DATE] as date)  
    FROM mydb 

Ale ten komunikat:

Msg 241, poziom 16, Stan 1, wiersz 2
Konwersja nie powiodła się podczas przekształcania daty i/lub czasu z ciągu znaków.

+0

Hmmm .. littleconfused tutaj. Czy ta konwersja nie jest automatycznie obsługiwana? – Coffee

+0

wypróbuj SELECT CONVERT (DATETIME, '20080107') – pavanred

+0

@Aaron Bertrand - Rozumiem twój punkt widzenia. –

Odpowiedz

16

Błąd występuje, ponieważ Ty (lub ktokolwiek zaprojektował ten stół) have a bunch of dates in VARCHAR. Dlaczego ty (lub ktokolwiek zaprojektował tę tabelę) przechowujesz daty jako ciągi? Czy ty (lub ktokolwiek zaprojektował ten stół) również przechowuje wynagrodzenia i ceny oraz odległości jako struny?

znaleźć wartości, które są przyczyną problemów (tak, Ty (lub kto zaprojektował tabela) można je naprawić):

SELECT GRADUATION_DATE FROM mydb 
    WHERE ISDATE(GRADUATION_DATE) = 0; 

Bet mieć co najmniej jeden wiersz. Napraw te wartości, a następnie USTAW TABELĘ. Albo zapytaj tego, kto zaprojektował stół, by USTAWIĆ STÓŁ. Naprawdę ładnie.

ALTER TABLE mydb ALTER COLUMN GRADUATION_DATE DATE; 

Teraz nie trzeba się martwić o formatowaniu - zawsze można sformatować jako YYYYMMDD lub YYYY-MM-DD na kliencie, lub za pomocą CONVERT w SQL. Kiedy masz ważny datę jako łańcuch znaków, można użyć:

SELECT CONVERT(CHAR(10), '20120101', 120); 

... ale to jest lepiej zrobić na kliencie (jeśli w ogóle).

Popularny termin - śmieci, śmieci. Nigdy nie będziesz w stanie przekonwertować na randkę (nie przejmuj się konwersją na string w określonym formacie), jeśli twój wybór typu danych (lub wybór typu danych tego, kto zaprojektował tabelę) nieodłącznie pozwala na umieszczenie śmieci w twoim stole . Proszę napraw to. Lub zapytaj, kto zaprojektował stół (znowu, naprawdę fajnie), aby to naprawić.

+0

Masz rację, było kilka brakujących wartości, których nie widziałem na środku stołu. Dzięki za przypomnienie mi o funkcji "isdate()". – screechOwl

+6

Widzę to cały czas w danych na komputerze mainframe. Db2 dla iSeries/AS400. Post jest rodzajem rantu, który zakłada, że ​​użytkownik ma kontrolę nad traktowaniem dat jako łańcuchów. Za dużo rantu, za mało odpowiedzi. – smoore4

+1

@ SQLDBA Musiałem przegapić, gdzie OP - który dwa lata temu przyjął tę odpowiedź - stwierdził, że korzystali z danych systemu mainframe, których nie mogli zmienić. Jeśli to były dane na temat komputerów mainframe, nie można ich zmienić, gdzie jest twoja odpowiedź na pytanie, jak to rozwiązać? Jeśli komputer mainframe ma zapisane '20130232', możesz podać więcej odpowiedzi, mniej rant? –

6

Zastosowanie SELECT CONVERT(date, '20140327')

W twoim przypadku,

SELECT [FIRST_NAME], 
     [MIDDLE_NAME], 
     [LAST_NAME], 
     CONVERT(date, [GRADUATION_DATE])  
FROM mydb 
-1

W Twoim przypadku powinno być:

Select convert(datetime,convert(varchar(10),GRADUATION_DATE,120)) as 
'GRADUATION_DATE' from mydb 
+0

Dzięki za pracę w Ms SQl 2005 –