Chuyển đổi không thành công khi chuyển đổi ngày và / hoặc thời gian từ chuỗi ký tự trong khi chèn datetime


164

Tôi đã cố gắng tạo một bảng như sau,

create table table1(date1 datetime,date2 datetime);

Đầu tiên tôi đã thử chèn các giá trị như dưới đây,

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

Nó đã đưa ra lỗi nói,

Không thể chuyển đổi varchar thành datetime

Sau đó, tôi đã thử định dạng bên dưới là một trong những bài đăng được đề xuất bởi stackoverflow của chúng tôi,

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

Nhưng tôi vẫn nhận được lỗi nói,

Chuyển đổi không thành công khi chuyển đổi ngày và / hoặc thời gian từ chuỗi ký tự

Bất kỳ đề xuất?


2
@Damien_The_Unbeliever như bạn đã nói tôi đã giới thiệu bài đăng này stackoverflow.com/questions/12957635/ trước khi đặt câu hỏi này. Họ yêu cầu chúng tôi sử dụng các giá trị 'insert table1 (Phê duyệt) (convert (datetime, '18 -06-12 10:34:09 PM', 5)); ' nhưng nó không hoạt động
Mari

Câu trả lời:


163

Có nhiều định dạng được SQL Server hỗ trợ - xem Sách trực tuyến MSDN trên CAST và CONVERT . Hầu hết các định dạng này phụ thuộc vào cài đặt bạn có - do đó, các cài đặt này có thể hoạt động một số lần - và đôi khi không.

Cách để giải quyết vấn đề này là sử dụng định dạng ngày ISO-8601 (được điều chỉnh một chút) được SQL Server hỗ trợ - định dạng này luôn hoạt động - bất kể cài đặt ngôn ngữ và định dạng máy chủ SQL của bạn.

Các định dạng ISO-8601 được hỗ trợ bởi SQL Server có hai hương vị:

  • YYYYMMDDchỉ ngày (không có phần thời gian); lưu ý ở đây: không có dấu gạch ngang! , điều đó rất quan trọng! YYYY-MM-DDKHÔNG phụ thuộc vào các thiết lập DateFormat trong SQL Server của bạn và sẽ không làm việc trong mọi tình huống!

hoặc là:

  • YYYY-MM-DDTHH:MM:SScho ngày và giờ - lưu ý ở đây: định dạng này có dấu gạch ngang (nhưng chúng có thể được bỏ qua) và cố định Tlà dấu phân cách giữa phần ngày và giờ của bạn DATETIME.

Điều này hợp lệ cho SQL Server 2000 và mới hơn.

Vì vậy, trong trường hợp cụ thể của bạn - sử dụng các chuỗi sau:

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

và bạn sẽ ổn (lưu ý: bạn cần sử dụng định dạng 24 giờ quốc tế thay vì định dạng AM / PM 12 giờ cho việc này).

Ngoài ra : nếu bạn đang sử dụng SQL Server 2008 hoặc mới hơn, bạn cũng có thể sử dụng DATETIME2kiểu dữ liệu (thay vì đơn giản DATETIME) và hiện tại của bạn INSERTsẽ chỉ hoạt động mà không gặp vấn đề gì! :-) DATETIME2tốt hơn rất nhiều và ít kén chọn hơn đối với các chuyển đổi - và đó là loại dữ liệu ngày / giờ được đề xuất cho SQL Server 2008 hoặc mới hơn.

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  

Đừng hỏi tôi tại sao toàn bộ chủ đề này quá phức tạp và hơi khó hiểu - đó chỉ là cách nó diễn ra. Nhưng với YYYYMMDDđịnh dạng, bạn sẽ ổn đối với mọi phiên bản SQL Server và cho mọi cài đặt ngôn ngữ và định dạng ngày tháng trong SQL Server của bạn.


1
Cũng giống như một ghi chú, truyền dưới dạng DATETIME2 cũng hoạt động với 'YYYY-MM-DDTHH: MM: SSZ' (lưu ý 'Z' - Thời gian Zulu ở cuối để biểu thị dấu thời gian UTC). Tôi đã gặp lỗi này khi cố gắng chèn '2013-12-16T17: 21: 26Z' vào trường datetime. Chỉ cần làm rõ, ISO 8601 được hỗ trợ một phần. Nó không hỗ trợ thời gian của Zulu, mặc dù nó được đề cập trong tài liệu. Có lẽ đó là một số thiết lập mà tôi chưa có thời gian để tìm hiểu, nhưng trong trường hợp ai đó có cùng một vấn đề, hãy ghi nhớ điều đó.
Michał

3
Tôi có thể xác nhận rằng định dạng ngày 'YYYYMMDD' hoạt động tốt, đã thử nó trên SQL Server 2014, như một cách để chỉ định ngày theo nghĩa đen trong mệnh đề WHERE. Nhiều xe tăng tới
@marc_s

1
Điều DATETIME2 làm việc cho tôi. Trong trường hợp của tôi, tôi đã nhập một tập lệnh cơ sở dữ liệu từ SQLServer bằng tiếng Anh sang phiên bản tiếng Tây Ban Nha của nó, vì vậy mọi lúc đều có cùng một lỗi. Tôi chỉ đơn giản thay thế trong tập lệnh tất cả các khoảng thời gian "dưới dạng DATETIME" thành "như DATETIME2" và vấn đề đã được giải quyết.
Alejandro del Río

24

Việc chuyển đổi trong máy chủ SQL đôi khi không thành công do các định dạng Ngày hoặc Thời gian được sử dụng, Hoàn toàn là do bạn đang cố lưu trữ dữ liệu sai mà hệ thống không chấp nhận được.

Thí dụ:

Create Table MyTable (MyDate);

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

Máy chủ SQL sẽ đưa ra lỗi sau:

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

Lý do cho lỗi này chỉ đơn giản là không có ngày như vậy (29 tháng 2) trong năm (2015).


2
"Lý do cho lỗi này chỉ đơn giản là không có ngày như vậy (29 tháng 2) trong năm (2015)" Đây chính xác là lý do khiến tôi gặp phải lỗi này. Câu trả lời này có tính đến nguyên nhân phổ biến nhất của lỗi này, mà các câu trả lời khác thì không.
FirstFraktal

1
Tôi đã nhập dữ liệu từ một bảng Excel trong đó các giá trị null thực sự có "NULL" trong ô. Điều này đã được đặt thành một chuỗi "Null" trong bảng DB, vì vậy đã cố gắng chuyển đổi chuỗi "Null" thành datetime. Đáng lẽ phải làm trống các ô "NULL" trong Excel. Tôi là một thằng ngốc: /
karol

17

Câu trả lời đơn giản - 5 là "yy" của Ý và 105 là "yyyy" của Ý. Vì thế:

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

sẽ hoạt động chính xác, nhưng

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

sẽ đưa ra lỗi.

Tương tự như vậy,

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

sẽ báo lỗi, ở đâu

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

sẽ làm việc.


8

Chỉ cần cập nhật định dạng ngày như dưới đây

yyyy-MM-dd hh:MM:ss

Nó giải quyết vấn đề cho tôi và nó hoạt động tốt


2
Xin vui lòng đọc các câu trả lời khác đã được cung cấp. Định dạng này chỉ hoạt động với bạn vì DATEFORMATcài đặt phiên của bạn . Xác nhận điều này bằng cách chạy 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);. Nó sẽ hoạt động đáng tin cậy nếu bạn thêm Tdấu phân cách ( yyyy-MM-ddTHH:mm:ss).
Dan Guzman

1
Cảm ơn rất nhiều, đúng vậy, bạn đã giải quyết được vấn đề của mình và tôi đã đọc các câu trả lời khác được đưa ra ở đây
Pronab Roy

8

Bất cứ khi nào có thể nên tránh văn hóa ngày / giờ cụ thể văn hóa .

Có một số định dạng an toàn để cung cấp ngày / giờ theo nghĩa đen:

Tất cả các ví dụ cho 2016-09-15 17:30:00

ODBC (yêu thích của tôi, vì nó được xử lý như loại thực ngay lập tức)

  • {ts'2016-09-15 17:30:00'} - Tem thời gian
  • {d'2016-09-15'} - Chỉ ngày
  • {t'17:30:00'} --Chỉ thời gian

ISO8601 (tốt nhất cho mọi nơi )

  • '2016-09-15T17:30:00'- nhận thức được Tở giữa!

Chưa được kiểm chứng (rủi ro nhỏ để hiểu sai thành số)

  • '20160915' - chỉ dành cho ngày thuần túy

Tốt để ghi nhớ: Ngày không hợp lệ có xu hướng hiển thị với các lỗi lạ

  • Không có ngày 31 tháng 6 hoặc 30 tháng 2 ...

Thêm một lý do cho các lỗi chuyển đổi lạ: Lệnh thực hiện!

SQL-Server được biết là thực hiện mọi thứ theo thứ tự thực hiện mà người ta có thể không mong đợi. Tuyên bố bằng văn bản của bạn trông giống như việc chuyển đổi được thực hiện trước đó một số hành động liên quan đến loại diễn ra, nhưng công cụ quyết định - tại sao lại bao giờ - thực hiện chuyển đổi trong bước sau.

Đây là một bài viết tuyệt vời giải thích điều này với các ví dụ: Rusano.com: "t-sql-tests-do-no-imply-a-Sure-order-of-exec" và đây là câu hỏi liên quan .


3

cách tốt nhất là mã này

"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
Nếu bạn sử dụng backticks, thay vì khoảng trắng ban đầu, bạn sẽ nhận được từ.
Jesse W tại Z - Từ bỏ vào

2

Định dạng datetime thực sự chạy trên máy chủ sql là

yyyy-mm-dd hh:MM:ss

1
Không, điều này không đúng (ngoài sự không phù hợp của mM). Đọc bình luận của Dan Guzman cho câu trả lời của Pronab Roy. Và đọc các câu trả lời khác tại đây ...
Shnugo

2

Hãy thử điều này.

SQL Server dự kiến ​​ngày ở định dạng MM / DD / YYYY, Nếu tiếng Anh được đặt làm ngôn ngữ mặc định của bạn. Đây là cách lưu giá trị ngày tháng vào cơ sở dữ liệu sql2008. Loại trường của tôi là datetime trong cơ sở dữ liệu.dpdob là tên ngày của tôi.

           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

Bây giờ sử dụng dob trong truy vấn chèn của bạn.


1

Bạn có thể thử mã này

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

1

Tôi đã có vấn đề này khi cố gắng nối getdate() vào một chuỗi mà tôi đang chèn vào trường nvarchar.

Tôi đã thực hiện một số phân vai để có được xung quanh nó:

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

Đó là một ví dụ vệ sinh. Phần quan trọng của điều đó là:

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

Đúc ngày tháng datetime2, sau đó như nvarcharđể nối nó.


1

Tôi đã thử cái này và nó hoạt động với tôi:

SELECT CONVERT(date, yourDate ,104)

0

đặt Văn hóa sang tiếng Anh từ tệp web.config

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

ví dụ nếu bạn đặt văn hóa thành tiếng ả rập thì thime sẽ

22/09/2017 02:16:57

và bạn gặp lỗi: Chuyển đổi thất bại khi chuyển đổi ngày và / hoặc thời gian từ chuỗi ký tự trong khi chèn datetime



0

Đối với tôi điều này đã làm việc:

INSERT INTO [MyTable]
           ([ValidFrom]
           ,[ValidTo])
       VALUES
           ('2020-01-27 14:54:11.000'
           ,'2023-01-27 14:52:50.000')
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.