Tarih saati eklenirken karakter dizesinden tarih ve / veya saat dönüştürülürken dönüştürme başarısız oldu


164

Aşağıdaki gibi bir tablo oluşturmaya çalışıyordum,

create table table1(date1 datetime,date2 datetime);

Önce aşağıdaki gibi değerler eklemeyi denedim,

insert into table1 values('21-02-2012 6:10:00 PM','01-01-2001 12:00:00 AM');

Hata verdi,

Varchar tarih tarihine dönüştürülemiyor

Sonra aşağıdaki biçimi stackoverflow tarafından önerilen yazı biri olarak denedim,

insert into table1 values(convert(datetime,'21-02-2012 6:10:00 PM',5)
                          ,convert(datetime,'01-01-2001 12:00:00 AM',5));

Ama yine de şu hatayı alıyorum:

Karakter dizesinden tarih ve / veya saat dönüştürülürken dönüştürme başarısız oldu

Baska öneri?


2
Dediğin gibi @Damien_The_Unbeliever bu soruyu sormadan önce bu yazı stackoverflow.com/questions/12957635/… daha önce bahsetmiştim . Bizden 'table1 (onay tarihi) değerlerini kullanmamızı istediler (convert (datetime, '18 -06-12 10:34:09 PM', 5)); ' ama çalışmıyor
Mari

Yanıtlar:


163

SQL Server tarafından desteklenen birçok biçim vardır - CAST ve CONVERT üzerinde MSDN Books Online'a bakın . Bu biçimlerin çoğu , hangi ayarlara sahip olduğunuza bağlıdır - bu nedenle, bu ayarlar bazen işe yarayabilir - bazen de çalışmayabilir.

Bunu çözmek için bir yol (biraz adapte) kullanmaktır ISO-8601 tarih biçimi , SQL Server tarafından desteklenmektedir - Bu biçim işleri hep - olursa olsun SQL Server dil ve dateformat ayarların.

ISO-8601 biçiminde SQL Server tarafından desteklenen iki şekilde sağlanır:

  • YYYYMMDDsadece tarihler için (zaman bölümü yok); not: tire yok! , bu çok önemli! YYYY-MM-DDolduğu DEĞİL SQL Server dateformat ayarlarından bağımsız ve olacak DEĞİL her durumda çalışmayabilir!

veya:

  • YYYY-MM-DDTHH:MM:SStarihler ve saatler için - burada not: Bu biçim vardır tire (ama olabilir atlanabilir) ve sabit Taramalarınızdan tarih ve saat kısmı arasında ayırıcı olarak DATETIME.

Bu, SQL Server 2000 ve daha yeni sürümler için geçerlidir.

Somut durumunuzda - şu dizeleri kullanın:

insert into table1 values('2012-02-21T18:10:00', '2012-01-01T00:00:00');

ve iyi olmalısınız (not: bunun için 12 saatlik ÖÖ / ÖS biçimi yerine uluslararası 24 saatlik biçimi kullanmanız gerekir ).

Alternatif olarak : SQL Server 2008 veya daha yeni bir DATETIME2sürüm kullanıyorsanız, veri türünü de (düz yerine DATETIME) kullanabilirsiniz ve akımınız INSERTherhangi bir sorun olmadan çalışır! :-) DATETIME2dönüşümler çok daha iyi ve çok daha az seçici - ve SQL Server 2008 veya daha yeni için tavsiye tarih / saat veri türleri zaten.

SELECT
   CAST('02-21-2012 6:10:00 PM' AS DATETIME2),     -- works just fine
   CAST('01-01-2012 12:00:00 AM' AS DATETIME2)   -- works just fine  

Bana tüm bu konunun neden bu kadar zor ve biraz kafa karıştırıcı olduğunu sorma - tam da bu şekilde. Ancak YYYYMMDDbiçimiyle, SQL Server'ın herhangi bir sürümü ve SQL Server'ınızdaki herhangi bir dil ve tarih biçimi ayarı için iyi olmalısınız.


1
Not olarak, DATETIME2 olarak yayınlama 'YYYY-AA-GGTHH: AA: SSZ' ile de çalışır (UTC zaman damgasını göstermek için sondaki 'Z' - Zulu zamanı not alın). '2013-12-16T17: 21: 26Z' datetime alanına eklemeye çalışırken bu hatayla karşılaştım. Açıklığa kavuşturmak için ISO 8601 kısmen desteklenmektedir. Belgelerde bahsedilmesine rağmen Zulu zamanını desteklemez. Muhtemelen anlamak için zamanım olmadı, ancak birinin aynı sorunu olması durumunda bunu aklınızda bulundurun.
Michał

3
'YYYYMMDD' tarih biçiminin düzgün çalıştığını doğrulayabilir, bir WHERE yan tümcesinde değişmez bir tarih belirtmenin bir yolu olarak SQL Server 2014'te denedim. @Marc_s için birçok tank
Giorgio Barchiesi

1
DATETIME2 işi benim için çalıştı. Benim durumumda bir SQLServer İngilizce bir veritabanı komut dosyası ispanyolca bir sürümü için ithal edildi, bu yüzden her zaman aynı hata. Ben sadece tüm "DATETIME" olarak "senaryo" DATETIME2 olarak "yerine değiştirdi ve sorun çözüldü.
Alejandro del Río

24

SQL Server'da dönüştürme bazen kullanılan Tarih veya Saat biçimleri nedeniyle başarısız olmaz, Bunun nedeni yalnızca sistem tarafından kabul edilemeyen yanlış verileri depolamaya çalışmanızdır.

Misal:

Create Table MyTable (MyDate);

Insert Into MyTable(MyDate) Values ('2015-02-29');

SQL sunucusu aşağıdaki hatayı atar:

Conversion failed when converting date and/or time from character string.

Bu hatanın nedeni, Yıl (2015) 'de böyle bir tarihin (29 Şubat) olmamasıdır.


2
"Bu hatanın nedeni, (2015) Yılında böyle bir tarih (29 Şubat) olmamasıdır." Tam olarak bu hatayı almamın nedeni buydu. Bu cevap, bu hatanın en yaygın nedenini, diğer cevapların vermediğini dikkate alır.
FirstFraktal

1
Null değerlerin aslında hücrede "NULL" olduğu bir Excel sayfasından veri aktardım. Bu DB tablosunda "Null" bir dize olarak ayarlandı, bu nedenle "Null" dizesini bir datetime dönüştürmeye çalışıyordu. Excel'de "NULL" hücreleri boşaltmış olmalıydı. Ben bir aptalım: /
karol

17

Basit cevap - 5 İtalyan "yy" ve 105 İtalyan "yyyy" dir. Bu nedenle:

SELECT convert(datetime,'21-02-12 6:10:00 PM',5)

düzgün çalışır, ancak

SELECT convert(datetime,'21-02-12 6:10:00 PM',105)

hata verecektir.

Aynı şekilde,

SELECT convert(datetime,'21-02-2012 6:10:00 PM',5)

hata verir, burada olduğu gibi

SELECT convert(datetime,'21-02-2012 6:10:00 PM',105)

çalışacak.


8

Tarih biçimini aşağıdaki gibi güncelleyin

yyyy-MM-dd hh:MM:ss

Sorunu benim için çözer ve iyi çalışır


2
Lütfen daha önce verilen diğer yanıtları okuyun. Bu biçim yalnızca oturum DATEFORMATayarınız nedeniyle sizin için çalışır . Bunu çalıştırarak doğrulayın SET DATEFORMAT MDY;SELECT CAST('2017-08-07 00:00:00' AS datetime); SET DATEFORMAT DMY;SELECT CAST('2017-08-07 00:00:00' AS datetime);. Bir Tayırıcı ( yyyy-MM-ddTHH:mm:ss) eklerseniz güvenilir bir şekilde çalışır .
Dan Guzman

1
Çok teşekkürler evet haklısın sorunumu çözdü ve burada verilen diğer cevapları okudum
Pronab Roy

8

Mümkün olduğunda, kültüre özgü tarih / saat değişmezlerinden kaçınılmalıdır .

Bir tarih / saati değişmez olarak sağlamak için bazı güvenli biçimler vardır :

İçin tüm örnekler 2016-09-15 17:30:00

ODBC (en sevdiğim, hemen gerçek tür olarak ele alındığı için )

  • {ts'2016-09-15 17:30:00'} --Zaman Damgası
  • {d'2016-09-15'} - Sadece tarih
  • {t'17:30:00'} - Sadece saat

ISO8601 ( her yer için en iyisi )

  • '2016-09-15T17:30:00'- ortada farkında olun T!

İşlem görmemiş (sayı olarak yanlış yorumlanma riski)

  • '20160915' - sadece saf tarih için

Unutmamak gerekir: Geçersiz tarihler garip hatalarla ortaya çıkma eğilimindedir

  • 31 Haziran ya da 30 Şubat yok ...

Garip dönüşüm hatalarının bir nedeni daha: Yürütme sırası!

SQL-Server, bir şey beklemiyor olabilir yürütme sırasına göre iyi biliyorum. Yazılı ifadeniz, dönüşümle ilgili bir tür işlem yapılmadan önce dönüşümün yapıldığı anlaşılıyor, ancak motor - neden her zaman - dönüşümü daha sonraki bir adımda yapmaya karar veriyor.

İşte bunu örneklerle açıklayan harika bir makale: Rusano.com: "t-sql-function-do-no-imply-a-belli-yürütme-sırası" ve işte ilgili soru .


3

en iyi yol bu kod

"select * from [table_1] where date between convert(date,'" + dateTimePicker1.Text + "',105) and convert(date,'" + dateTimePicker2.Text + "',105)"

2
convert(datetime2,((SUBSTRING( ISNULL(S2.FechaReal,e.ETA),7,4)+'-'+ SUBSTRING( ISNULL(S2.FechaReal,e.ETA),4,2)+'-'+ SUBSTRING( ISNULL(S2.FechaReal,e.ETA),1,2) + ' 12:00:00.127')))  as fecha,

1
Başlangıç ​​boşlukları yerine ters tırnaklar kullanırsanız, sözcük kaydırma özelliği elde edersiniz.
Jesse W at Z - SE

2

Aslında sql sunucusunda çalışan datetime biçimi

yyyy-mm-dd hh:MM:ss

1
Hayır, bu (uyumsuzluğundan yanında doğru değildir mve M). Dan Guzman'ın Pronab Roy'un cevabına yaptığı yorumu okuyun. Ve diğer cevapları burada okuyun ...
Shnugo

2

Lütfen bunu deneyin.

İngilizce varsayılan diliniz olarak ayarlanmışsa SQL Server, tarihleri ​​MM / DD / YYYY biçiminde bekler. Datepicker değerini sql2008 veritabanına kaydediyorum. Alan türüm veritabanında datetime.

           Dim test = dpdob.Text.Replace("-", "/")
           Dim parts As String() = test.Split(New Char() {"/"c})
           Dim firstPart As String = parts(0)
           Dim thirdPart As String = parts(2)
           Dim secondPart As String = parts(1)
           Dim test1 = secondPart + "/" + firstPart + "/" + thirdPart
           Dim dob = test1

Şimdi ekleme sorgunuzda dob kullanın.


1

Bu kodu deneyebilirsiniz

select (Convert(Date, '2018-04-01'))

1

Birleştirmeye çalışırken bu sorunu yaşadım getdate() bir nvarchar alanına bir dizeye .

Ben almak için bazı döküm yaptım:

 INSERT INTO [SYSTEM_TABLE] ([SYSTEM_PROP_TAG],[SYSTEM_PROP_VAL]) VALUES 
   (
    'EMAIL_HEADER',
    '<h2>111 Any St.<br />Anywhere, ST 11111</h2><br />' + 
        CAST(CAST(getdate() AS datetime2) AS nvarchar) + 
    '<br /><br /><br />'
   )

Temizlenmiş bir örnek. Bunun önemli kısmı:

...' + CAST(CAST(getdate() AS datetime2) AS nvarchar) + '...

Tarihi datetime2, ardından nvarcharbirleştirmek üzere olarak yayınladı.



0

Web.config dosyasından Culture'ı ingilizce olarak ayarlayın

  <globalization uiCulture="en-US" culture="en-US" />

örneğin kültürü arapçaya ayarlarsanız,

22/09/2017 02:16:57 ص

ve hatayı alıyorsunuz: datetime eklenirken karakter dizesinden tarih ve / veya saat dönüştürülürken dönüştürme başarısız oldu



0

Benim için bu işe yaradı:

INSERT INTO [MyTable]
           ([ValidFrom]
           ,[ValidTo])
       VALUES
           ('2020-01-27 14:54:11.000'
           ,'2023-01-27 14:52:50.000')
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.