การแปลงล้มเหลวเมื่อแปลงวันที่และ / หรือเวลาจากสตริงอักขระขณะแทรกวันที่และเวลา


164

ฉันพยายามสร้างตารางดังนี้

create table table1(date1 datetime,date2 datetime);

ก่อนอื่นฉันลองใส่ค่าดังนี้

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

มันทำให้เกิดข้อผิดพลาดในการพูด

ไม่สามารถแปลง varchar เป็น datetime

จากนั้นฉันลองรูปแบบด้านล่างเป็นหนึ่งในโพสต์ที่แนะนำโดย stackoverflow ของเรา

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

แต่ฉันยังคงได้รับข้อผิดพลาดที่บอกว่า

การแปลงล้มเหลวเมื่อแปลงวันที่และ / หรือเวลาจากสตริงอักขระ

ข้อเสนอแนะใด ๆ


2
@Damien_The_Unbeliever ตามที่คุณบอกว่าฉันได้แนะนำโพสต์นี้แล้วstackoverflow.com/questions/12957635/ก่อนที่จะถามคำถามนี้ พวกเขาขอให้เราใช้ค่า 'insert table1 (approvaldate) (แปลง (วันที่, '18 -06-12 10:34:09 PM', 5)); ' แต่มันใช้ไม่ได้
Mari

คำตอบ:


163

มีหลายรูปแบบการสนับสนุนจาก SQL Server เป็น - ดูMSDN หนังสือออนไลน์ในนักแสดงและแปลง รูปแบบเหล่านั้นส่วนใหญ่จะขึ้นอยู่กับการตั้งค่าที่คุณมี - ดังนั้นการตั้งค่าเหล่านี้อาจใช้งานได้บางครั้ง - และบางครั้งก็ไม่

วิธีการแก้ปัญหานี้คือการใช้รูปแบบวันที่ ISO-8601 (ดัดแปลงเล็กน้อย) ที่ SQL Server รองรับ - รูปแบบนี้ใช้งานได้ตลอดเวลา - ไม่ว่าภาษา SQL Server ของคุณและการตั้งค่ารูปแบบวันที่

รูปแบบ ISO-8601ได้รับการสนับสนุนโดย SQL Server มาในสองรสชาติ:

  • YYYYMMDDสำหรับวันที่เพียง (ไม่มีส่วนเวลา); หมายเหตุที่นี่: ไม่มีขีดกลาง! นั่นสำคัญมาก! YYYY-MM-DDคือไม่ได้เป็นอิสระจากการตั้งค่า dateformat ใน SQL Server ของคุณและจะไม่ทำงานในทุกสถานการณ์!

หรือ:

  • YYYY-MM-DDTHH:MM:SSสำหรับวันที่และเวลา - โน้ตที่นี่: รูปแบบนี้มีขีดคั่น ( แต่พวกเขาสามารถจะละเว้น) และคงเป็นตัวคั่นระหว่างวันที่และเวลาส่วนหนึ่งของคุณTDATETIME

สิ่งนี้ใช้ได้สำหรับ SQL Server 2000 และใหม่กว่า

ดังนั้นในกรณีที่เป็นรูปธรรมของคุณ - ใช้สตริงเหล่านี้:

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

และคุณควรจะดี (หมายเหตุ: คุณต้องใช้รูปแบบ24 ชั่วโมงสากลแทนรูปแบบ AM / PM 12 ชั่วโมงสำหรับเรื่องนี้)

อีกทางเลือกหนึ่ง : หากคุณใช้ SQL Server 2008หรือใหม่กว่าคุณสามารถใช้DATETIME2ประเภทข้อมูล (แทนที่จะเป็นแบบธรรมดาDATETIME) และปัจจุบันของคุณINSERTจะทำงานได้โดยไม่มีปัญหา! :-) DATETIME2ดีขึ้นมากและเลือกน้อยมากสำหรับการแปลง - และเป็นชนิดข้อมูลวันที่ / เวลาที่แนะนำสำหรับ SQL Server 2008 หรือใหม่กว่า

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  

อย่าถามฉันว่าทำไมหัวข้อทั้งหมดนี้จึงค่อนข้างยุ่งยากและสับสน - นั่นเป็นวิธีที่มันเป็น แต่ด้วยYYYYMMDDรูปแบบคุณควรใช้ได้กับ SQL Server ทุกรุ่นและสำหรับการตั้งค่าภาษาและรูปแบบวันที่ใน SQL Server ของคุณ


1
เช่นเดียวกับโน้ตการคัดเลือกนักแสดงเมื่อ DATETIME2 ยังทำงานร่วมกับ 'YYYY-MM-DDTHH: MM: SSZ' (หมายเหตุ 'Z' - เวลาซูลูในตอนท้ายเพื่อแสดงเวลาประทับ UTC) ฉันมีข้อผิดพลาดนี้ขณะพยายามแทรก '2013-12-16T17: 21: 26Z' ในฟิลด์ datetime เพียงชี้แจงเท่านั้น ISO 8601 รองรับบางส่วน ไม่สนับสนุนเวลาของ Zulu แม้จะมีการกล่าวถึงในเอกสารประกอบ อาจเป็นการตั้งค่าบางอย่างที่ฉันยังไม่มีเวลาคิด แต่ในกรณีที่บางคนมีปัญหาเดียวกันให้ระลึกไว้เสมอ
Michał

3
ฉันสามารถยืนยันได้ว่ารูปแบบวันที่ 'YYYYMMDD' ทำงานได้ดีลองบน SQL Server 2014 เป็นวิธีการระบุวันที่ที่แท้จริงในส่วนคำสั่ง WHERE รถถังมากมายที่ @marc_s
Giorgio Barchiesi

1
สิ่งที่ DATETIME2 ใช้งานได้สำหรับฉัน ในกรณีของฉันฉันกำลังนำเข้าสคริปต์ฐานข้อมูลจาก SQLServer เป็นภาษาอังกฤษไปยังเวอร์ชั่นภาษาสเปนดังนั้นทุกครั้งที่มีข้อผิดพลาดเดียวกัน ฉันเพียงแทนที่สคริปต์ทั้งหมดเป็น "DATETIME" เพื่อ "เป็น DATETIME2" และแก้ไขปัญหา
Alejandro del Río

24

การแปลงในเซิร์ฟเวอร์ SQL ล้มเหลวในบางครั้งไม่ใช่เพราะรูปแบบวันที่หรือเวลาที่ใช้เป็นเพียงเพราะคุณพยายามจัดเก็บข้อมูลที่ไม่ถูกต้องที่ระบบไม่ยอมรับ

ตัวอย่าง:

Create Table MyTable (MyDate);

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

เซิร์ฟเวอร์ SQL จะแสดงข้อผิดพลาดต่อไปนี้:

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

สาเหตุของข้อผิดพลาดนี้คือไม่มีวันดังกล่าว (ก.พ. -29) ในปี (2558)


2
"เหตุผลที่ทำให้เกิดข้อผิดพลาดนี้ก็คือไม่มีวันดังกล่าว (ก.พ. -29) ในปี (2558)" นี่เป็นเหตุผลที่ฉันได้รับข้อผิดพลาดนี้อย่างแน่นอน คำตอบนี้คำนึงถึงสาเหตุที่พบบ่อยที่สุดของข้อผิดพลาดนี้ว่าคำตอบอื่นไม่ได้
FirstFraktal

1
ฉันนำเข้าข้อมูลจากแผ่นงาน Excel โดยที่ค่า Null มีอยู่จริงในเซลล์ สิ่งนี้ถูกตั้งค่าเป็นสตริง "Null" ในตาราง DB ดังนั้นพยายามแปลงสตริง "Null" เป็น datetime ควรล้างเซลล์ "NULL" ใน Excel ฉันเป็นคนงี่เง่า: /
karol

17

คำตอบง่ายๆ - 5 คืออิตาลี "yy" และ 105 คืออิตาลี "yyyy" ดังนั้น:

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

จะทำงานได้อย่างถูกต้อง แต่

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

จะให้ข้อผิดพลาด

ในทำนองเดียวกัน

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

จะให้ข้อผิดพลาดที่ไหน

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

จะทำงาน.


8

เพียงอัปเดตรูปแบบวันที่เหมือนร้อง

yyyy-MM-dd hh:MM:ss

มันแก้ปัญหาให้ฉันและมันใช้งานได้ดี


2
โปรดอ่านคำตอบอื่น ๆ ที่มีให้แล้ว รูปแบบนี้ใช้สำหรับคุณเท่านั้นเนื่องจากDATEFORMATการตั้งค่าเซสชันของคุณ 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);ตรวจสอบนี้โดยการทำงาน มันจะทำงานได้อย่างน่าเชื่อถือหากคุณเพิ่มTตัวคั่น ( yyyy-MM-ddTHH:mm:ss)
Dan Guzman

1
ขอบคุณมากใช่คุณพูดถูกมันแก้ปัญหาของฉันและฉันอ่านคำตอบอื่น ๆ ที่ได้รับที่นี่
Pronab Roy

8

เมื่อใดก็ตามที่เป็นไปได้ควรหลีกเลี่ยงวันที่ / เวลาตัวอักษรเฉพาะวัฒนธรรม

มีรูปแบบที่ปลอดภัยบางรูปแบบที่จะให้วันที่ / เวลาตามตัวอักษร:

ตัวอย่างทั้งหมดสำหรับ 2016-09-15 17:30:00

ODBC (สิ่งที่ฉันชอบเพราะมันเป็นประเภทจริงทันที)

  • {ts'2016-09-15 17:30:00'} - ประทับเวลา
  • {d'2016-09-15'} - วันที่เท่านั้น
  • {t'17:30:00'} - เวลาเท่านั้น

ISO8601 (ดีที่สุดสำหรับทุกที่ )

  • '2016-09-15T17:30:00'- ตระหนักถึงTตรงกลาง!

ไม่ถูกต้อง (ความเสี่ยงเล็กน้อยในการตีความตัวเลขเป็นจำนวนที่ผิด)

  • '20160915' - เพียงเพื่อวันที่บริสุทธิ์

ดีที่ควรทราบ: วันที่ไม่ถูกต้องมักจะปรากฏขึ้นพร้อมกับข้อผิดพลาดแปลก ๆ

  • ไม่มีวันที่ 31 มิถุนายนหรือ 30 กุมภาพันธ์คือ ...

อีกหนึ่งเหตุผลสำหรับข้อผิดพลาดในการแปลงที่แปลก: คำสั่งของการดำเนินการ!

SQL-Server รู้ดีว่าต้องทำอะไรตามคำสั่งของการดำเนินการอย่างหนึ่งที่อาจไม่คาดคิด ข้อความที่เป็นลายลักษณ์อักษรของคุณดูเหมือนว่าจะมีการแปลงมาก่อนมีการดำเนินการที่เกี่ยวข้องกับบางประเภท แต่เอ็นจิ้นจะทำการตัดสินใจว่าจะแปลงเป็นอย่างไรในภายหลัง

นี่คือบทความดีดีอธิบายนี้ด้วยตัวอย่าง: Rusano.com: "T-SQL ฟังก์ชั่นทำ-no-บ่งบอก-a-บางคำสั่งของการดำเนินการ"และนี่คือคำถามที่เกี่ยวข้อง


3

วิธีที่ดีที่สุดคือรหัสนี้

"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
หากคุณใช้ backticks แทนที่จะเว้นช่องว่างเริ่มต้นคุณจะได้รับการตัดคำ
Jesse W ที่ Z - เลิก

2

รูปแบบวันที่และเวลาจริงที่ทำงานบนเซิร์ฟเวอร์ sql คือ

yyyy-mm-dd hh:MM:ss

1
ไม่สิ่งนี้ไม่เป็นความจริง (นอกเหนือจากที่ไม่ตรงกัน mและM) อ่านความคิดเห็นของ Dan Guzman ต่อคำตอบของ Pronab Roy และอ่านคำตอบอื่น ๆ ได้ที่นี่ ...
Shnugo

2

โปรดลองสิ่งนี้

SQL Server คาดว่าวันที่ในรูปแบบ MM / DD / YYYY ถ้าภาษาอังกฤษถูกตั้งค่าเป็นภาษาเริ่มต้นของคุณที่นี่กำลังบันทึกค่า datepicker ไปยังฐานข้อมูล sql2008 ประเภทเขตข้อมูลของฉันคือ datetime ใน database.dpdob เป็นชื่อ datepicker ของฉัน

           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

ตอนนี้ใช้ dob ในแบบสอบถามแทรกของคุณ



1

ฉันมีปัญหานี้เมื่อพยายามเชื่อมต่อ getdate()เป็นสตริงที่ฉันใส่ลงในฟิลด์ nvarchar

ฉันทำการคัดเลือกเพื่อหลีกเลี่ยง:

 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 />'
   )

นั่นเป็นตัวอย่างที่ถูกสุขลักษณะ ส่วนสำคัญของที่:

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

ส่งวันที่datetime2แล้วจึงนำnvarcharไปต่อกัน



0

ตั้ง Culture เป็นภาษาอังกฤษจากไฟล์ web.config

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

ตัวอย่างเช่นถ้าคุณตั้งค่าวัฒนธรรมเป็นภาษาอาหรับ thime จะเป็น

22/09/2017 02:16:57 ص

และคุณได้รับข้อผิดพลาด: การแปลงล้มเหลวเมื่อแปลงวันที่และ / หรือเวลาจากสตริงอักขระขณะแทรกวันที่และเวลา



0

สำหรับฉันแล้วสิ่งนี้ได้ผล:

INSERT INTO [MyTable]
           ([ValidFrom]
           ,[ValidTo])
       VALUES
           ('2020-01-27 14:54:11.000'
           ,'2023-01-27 14:52:50.000')
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.