Zapytanie SQL, aby wstawić datę i godzinę w programie SQL Server

137

Chcę wstawić datetimewartość do tabeli (SQL Server) za pomocą poniższego zapytania sql

insert into table1(approvaldate)values(18-06-12 10:34:09 AM);

Ale otrzymuję ten komunikat o błędzie. Incorrect syntax near '10'.

Wypróbowałem to z cytatami

insert into table1(approvaldate)values('18-06-12 10:34:09 AM');

Otrzymuję ten komunikat o błędzie Cannot convert varchar to datetime

Uprzejma pomoc! Dzięki.

Shee
źródło

Odpowiedzi:

238

Będziesz chciał użyć RRRRMMDD do jednoznacznego określenia daty w SQL Server.

insert into table1(approvaldate)values('20120618 10:34:09 AM');

Jeśli jesteś żonaty z dd-mm-yy hh:mm:ss xmformatem, będziesz musiał użyć CONVERT z określonym stylem.

insert into table1 (approvaldate)
       values (convert(datetime,'18-06-12 10:34:09 PM',5));

5oto styl na włoskie randki. Cóż, nie tylko Włosi, ale jest to kultura, której przypisuje się w Books Online .

RichardTheKiwi
źródło
1
Dziękuję… To działa. Przy okazji, czy nie można wprowadzić w formacie DD-MM-RR?
Shee
@RichardTheKiwi what does the signify 5?
Shee
@Shee zobacz dodaną stopkę do odpowiedzi
RichardTheKiwi,
4
Stoję poprawiony - jeśli używasz YYYYMMDD HH:MM:SS(w formacie 24-godzinnym - formatu światowego, każdy oprócz USA używa tego, nie tylko wojsko ...) bez myślników - działa, nawet w przypadku Britishjęzyka. Jeśli YYYY-MM-DD HH:MM:SSjednak użyjesz , nie powiedzie się - w takim przypadku (z myślnikami) musisz oddzielić datę i godzinę Tliterałem.
marc_s
1
@Shee Spójrz na SET DATEFORMAToświadczenie . To jest ustawienie dla pojedynczego połączenia, ale można je określić dla całego serwera. Możesz również określić, SET LANGUAGEaby kontrolować takie rzeczy, jak znak używany jako podstawa i tym podobne, a format daty będzie dziedziczyć po tym (ponownie na poziomie serwera lub połączenia). Po prostu domyślnym jest angielski amerykański, a mdy to format amerykański. ymd z datami 4-letnimi zawsze jednak działa.
Bacon Bits
29

Bardziej niezależnym od języka wyborem literałów łańcuchowych jest międzynarodowy standard ISO 8601 w formacie „RRRR-MM-DDTgg: mm: ss”. Użyłem zapytania SQL poniżej, aby przetestować format i rzeczywiście działa we wszystkich językach SQL w sys.syslanguages :

declare @sql nvarchar(4000)

declare @LangID smallint
declare @Alias sysname

declare @MaxLangID smallint
select @MaxLangID = max(langid) from sys.syslanguages

set @LangID = 0

while @LangID <= @MaxLangID
begin

    select @Alias = alias
    from sys.syslanguages
    where langid = @LangID

    if @Alias is not null
    begin

        begin try
            set @sql = N'declare @TestLang table (langdate datetime)
    set language ''' + @alias + N''';
    insert into @TestLang (langdate)
    values (''2012-06-18T10:34:09'')'
            print 'Testing ' + @Alias

            exec sp_executesql @sql
        end try
        begin catch
            print 'Error in language ' + @Alias
            print ERROR_MESSAGE()
        end catch
    end

    select @LangID = min(langid)
    from sys.syslanguages
    where langid > @LangID
end

Zgodnie z sekcją Formaty daty i godziny literału ciągu w witrynie Microsoft TechNet, standardowy format daty ANSI Standard SQL „RRRR-MM-DD hh: mm: ss” powinien być „wielojęzyczny”. Jednak przy użyciu tego samego zapytania format ANSI nie działa we wszystkich językach SQL.

Na przykład w języku duńskim będzie wiele błędów, takich jak następujące:

Błąd w języku duńskim Konwersja typu danych varchar na typ danych typu data i godzina spowodowała, że ​​wartość spoza zakresu.

Jeśli chcesz zbudować zapytanie w C # do uruchomienia na SQL Server i musisz przekazać datę w formacie ISO 8601, użyj specyfikatora formatu „s” sortable :

string.Format("select convert(datetime2, '{0:s}'", DateTime.Now);
Paul Williams
źródło
Wygląda na to, że możesz użyć YYYYMMDDtylko daty i albo YYYY-MM-DDThh:mm:ss(z myślnikami i tak, częścią Tmiędzy datą a godziną!) Lub YYYYMMDD HH:MM:SS(bez myślników, bez literału separacji), aby być naprawdę niezależnym od języka ...
marc_s
1
@marc_s: Dziękuję za komentarz. Zredagowałem moją odpowiedź, aby wspomnieć o formacie ISO 8601 (który zawiera literał T, jak wspomniałeś).
Paul Williams
wstaw do wartości @TestLang (langdate) ('2012-06-18T10: 34: 09') jest najlepszą odpowiedzią.
MERT DOĞAN,
22

Studio zarządzania tworzy skrypty takie jak:

insert table1 (foodate) values(CAST(N'2012-06-18 10:34:09.000' AS DateTime))
Eduardo Aguiar
źródło
9

musisz to dodać jak

insert into table1(date1) values('12-mar-2013');
nid
źródło
2

Nie ma potrzeby używania konwersji. Po prostu podaj ją jako cytowaną datę w formacie ISO 8601.
Tak jak to:

select * from table1 where somedate between '2000/01/01' and '2099/12/31'

Separator musi mieć postać /a i musi być otoczony pojedynczymi 'cudzysłowami.

Johan
źródło
1

Jeśli przechowujesz wartości w dowolnym języku programowania

Oto przykład w C #

Aby zapisać datę, musisz ją najpierw przekonwertować, a następnie zapisać

insert table1 (foodate)
   values (FooDate.ToString("MM/dd/yyyy"));

FooDate to zmienna datetime, która zawiera Twoją datę w Twoim formacie.

Pankaj
źródło
1

Napotykam na bardziej ogólny problem: pobieranie różnych (i niekoniecznie znanych) formatów daty i godziny i wstawianie ich do kolumny datetime. Rozwiązałem to za pomocą tego stwierdzenia, które w końcu stało się funkcją skalarną (stosowną dla ODBC kanonicznego, amerykańskiego, ANSI i brytyjskiego \ franchowego stylu daty - można ją rozwinąć):

insert into <tableName>(<dateTime column>) values(coalesce 
(TRY_CONVERT(datetime, <DateString, 121), TRY_CONVERT(datetime, <DateString>, 
101), TRY_CONVERT(datetime, <DateString>, 102), TRY_CONVERT(datetime, 
<DateString>, 103))) 
Guy E.
źródło