SQL - Việc chuyển đổi kiểu dữ liệu varchar thành kiểu dữ liệu datetime dẫn đến giá trị nằm ngoài phạm vi


89

Tôi đã gặp lỗi sau khi chạy SQL để chuyển đổi giá trị kiểu dữ liệu của tôi từ varcharsang datetime.

Msg 242, Mức 16, Trạng thái 3, Dòng 1 Việc chuyển đổi kiểu dữ liệu varchar thành kiểu dữ liệu datetime dẫn đến giá trị nằm ngoài phạm vi.

Tôi đã kiểm tra dữ liệu và không thấy bất kỳ điều gì khác lạ: Chạy các kiểm tra sau và tất cả đều không trả lại kết quả

SELECT [Date] from table where [DATe] is null
SELECT [Date] from table where [DATe] = ''
SELECT [Date] from table where LEN([date])> 10
SELECT [Date] from table where LEN([date])< 10
SELECT top 100 [Date] , SUBSTRING([date],4,2) from [table where convert(int, SUBSTRING([date],4,2)) < 1 or convert(int, SUBSTRING([date],4,2)) > 12
SELECT top 100 [Date] , SUBSTRING([date],1,2) from table where convert(int, SUBSTRING([date],4,2)) < 1 or convert(int, SUBSTRING([date],4,2)) > 31

Có điều gì khác đáng xem xét và có thể có giá trị gợi ý hoặc trợ giúp về vấn đề này không? Dường như không thể hiểu được nó.


3
Kiểu dữ liệu của cột ngày là gì? Bạn có thể cho tôi xem lược đồ bảng và thông báo rằng lỗi xảy ra trên không?
Spikeh

3
câu nào trong sáu câu lệnh SQL bạn đã cung cấp không thành công?
Mureinik

1
Sáu câu lệnh đều hoạt động và xác minh không có vấn đề gì với dữ liệu.
user23495,

3
bạn chưa kiểm tra các ngày không hợp lệ, ví dụ: 2013-10-31 hoặc 2013-02-30. Có lẽ, lỗi mà bạn đang phải đối mặt, đề cập đến loại đó ngày có vấn đề
Dalen

2
Xin chào Dalen, tôi đã thực hiện kiểm tra này. Cách dữ liệu được thiết lập là 31/10/2013, 30/10/2013. Nó ở định dạng Vương quốc Anh. Điều này có ảnh hưởng gì không khi cố gắng thay đổi một loại cột, tôi không nghĩ là nó sẽ xảy ra.
user23495 30/12/13

Câu trả lời:


85

Tôi đã phải đối mặt với vấn đề tương tự một tuần trước. Vấn đề là với thiết lập múi giờ. Chỉ định ở các định dạng khác như mm / dd / yyyy (thường hoạt động).

Việc chỉ định ngày là 30/12/2013 dẫn đến lỗi cho tôi. Tuy nhiên, chỉ định nó là định dạng mm / dd / yyyy đã hoạt động.

Nếu bạn cần chuyển đổi đầu vào của mình, bạn có thể thử xem xét CONVERTphương pháp. Cú pháp là

CONVERT(VARCHAR,@your_date_Value,103)

CONVERT(VARCHAR, '12/30/2013', 103)

Kết thúc 103 là định dạng ngày giờ.

Tham khảo liên kết này để biết các định dạng chuyển đổi và đọc thêm. https://www.w3schools.com/sql/func_sqlserver_convert.asp


1
Cảm ơn người bạn đời đã giúp đỡ. Tôi đã cố gắng chuyển đổi điều này nhưng vẫn không gặp bất kỳ may mắn nào. Nó có thể là do bảng vẫn còn một varchar hoặc bất cứ điều gì khác có thể gây ra lỗi này?
user23495,

2
Sẽ rất hữu ích nếu bạn đăng dữ liệu mẫu của mình (trong bảng). Trong nhận xét, bạn nói rằng bạn muốn nó ở định dạng yyyy-mm-dd. Vì vậy, hãy thử điều này SELECT CONVERT(char(10), GetDate(),126). Chỉ cần thay thế GETDATE () bằng giá trị cần thiết.
Mahe

61

Tôi gặp phải vấn đề này do một sai lầm ngớ ngẩn. Hãy chắc chắn rằng ngày thực sự tồn tại!

Ví dụ:

Ngày 31 tháng 9 năm 2015 không tồn tại.

EXEC dbo.SearchByDateRange @Start = '20150901' , @End = '20150931'

Vì vậy, điều này không thành công với thông báo:

Error converting data type varchar to datetime.

Để khắc phục, hãy nhập một ngày hợp lệ:

EXEC dbo.SearchByDateRange @Start = '20150901' , @End = '20150930'

Và nó thực thi tốt.


2
Vâng, tôi vừa tìm thấy ngày hết hạn là ngày 29 tháng 2 năm 2015 trong cơ sở dữ liệu mà tôi phải làm việc. Tôi tự hỏi làm thế nào nó vào đó. Tôi tự hỏi có bao nhiêu hơn là ở đó ...
Resource

4
Vừa sử dụng ép kiểu (SUBSTRING ([MyDateField], 1,2) dưới dạng số nguyên)> 31 và tìm thấy một bản ghi có ngày 60 của tháng 12. Ai đã nhập những thứ này, Tiến sĩ Suess?
SteveCav

3
Cảm ơn! Đây là vấn đề của tôi. Tôi có một số dữ liệu xấu trong bộ của mình - 01/01/1113, haha.
Sev09

2
Đối với tôi, tôi đã đặt sai chuỗi định dạng khi định dạng ngày để xây dựng câu lệnh SQL. Tôi đã sử dụng Format(DateTime.Now, "yyyymmdd")khi nó cần phải có đượcFormat(DateTime.Now, "yyyyMMdd")
Jay Imerman

1
Argh quy ước ngày của Mỹ! Đã cho tôi bối rối trong một thời gian, vì "ngày 26 tháng mười năm 2017" tức là, '26 -10-2017' là một ngày hoàn toàn hợp lệ :).
Antimon

29

Tôi đã gặp vấn đề tương tự gần đây. Cài đặt khu vực đã được thiết lập đúng cả trong ứng dụng và máy chủ cơ sở dữ liệu. Tuy nhiên, việc thực thi SQL dẫn đến

"Việc chuyển đổi kiểu dữ liệu varchar thành kiểu dữ liệu datetime dẫn đến giá trị nằm ngoài phạm vi".

Vấn đề là ngôn ngữ mặc định của người dùng db.

Để kiểm tra hoặc thay đổi nó trong SSMS, hãy đi tới Bảo mật -> Đăng nhập và nhấp chuột phải vào tên người dùng của người dùng chạy truy vấn. Chọn thuộc tính -> chung và đảm bảo rằng ngôn ngữ mặc định ở cuối hộp thoại là những gì bạn mong đợi.

Lặp lại điều này cho tất cả người dùng chạy truy vấn.


1
Điều này đã giúp tôi. Chỉ cần một chỉnh sửa nhỏ: ngôn ngữ mặc định của server loginkhông db user. top-password.com/blog/…
Baz Guvenkaya

1
Vì nó được đặt trong mã chương trình và tôi không có quyền truy cập vào mã, tôi đã thay đổi nó từ Englishthành British Englishvà nó đã hoạt động!
vaheeds

1
Tương tự cho tôi ahd để thay đổi tiếng Anh sang tiếng Anh Anh - Ali, bạn là một người tiết kiệm cuộc sống!
david-giorgi


4
Create procedure [dbo].[a]

@examdate varchar(10) ,
@examdate1 varchar(10)
AS
Select tbl.sno,mark,subject1,
Convert(varchar(10),examdate,103) from tbl
where 
(Convert(datetime,examdate,103)  >= Convert(datetime,@examdate,103) 
and (Convert(datetime,examdate,103) <=  Convert(datetime,@examdate1,103)))

5
Vui lòng thêm mô tả cho câu trả lời của bạn. Nó sẽ giúp người hỏi nắm bắt thêm câu trả lời của bạn.
Pramod S. Nikam

2

Tôi đã gặp vấn đề tương tự và xác định rằng vấn đề này phát sinh do SQL Server không thực hiện so sánh trên các ký tự được chuyển đổi thành số nguyên theo cách giống hệt nhau. Trong thử nghiệm của mình, tôi nhận thấy rằng một số so sánh của các ký tự được chuyển đổi, chẳng hạn như dấu chấm than, sẽ trả về lỗi chuyển đổi kiểu, trong khi các so sánh khác của các ký tự được chuyển đổi, chẳng hạn như khoảng trắng, sẽ được xác định là nằm ngoài phạm vi.

Mã mẫu này kiểm tra các tình huống có thể xảy ra khác nhau và trình bày giải pháp bằng cách sử dụng các câu lệnh REPLACE lồng nhau. REPLACE xác định xem có bất kỳ ký tự nào trong chuỗi không phải là số hoặc dấu gạch chéo hay không và nếu có, độ dài của chuỗi sẽ lớn hơn 0, do đó cho biết rằng có các ký tự 'xấu' và ngày tháng không hợp lệ .

DECLARE @str varchar(10)
SET @str = '12/10/2012'
IF convert(int, substring(@str,4,2)) <= 31 AND convert(int, substring(@str,4,2)) >= 1
    PRINT @str+': Passed Test'
    ELSE PRINT @str+': Failed Test'
GO

DECLARE @str varchar(10)
SET @str = '12/10/2012' 
PRINT 'Number of characters in ' + @str + ' that are not numerals or a slash (0 means the date is valid; all values greater than 0 indicate a problem): ' + convert(varchar(5),len(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(@str,'0',''),'1',''),'2',''),'3',''),'4',''),'5',''),'6',''),'7',''), '8',''),'9',''),'/',''),' ','+'))) --replace space with a + to avoid empty string
PRINT ''
GO

DECLARE @str varchar(10)
SET @str = '12/!0/2012'
    IF convert(int, substring(@str,4,2)) <= 31 AND convert(int, substring(@str,4,2)) >= 1
        PRINT @str+': Passed Test'
        ELSE PRINT @str+': Failed Test'
GO

DECLARE @str varchar(10)
SET @str = '12/!0/2012' 
PRINT 'Number of characters in ' + @str + ' that are not numerals or a slash (0 means the date is valid; all values greater than 0 indicate a problem): ' + convert(varchar(5),len(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(@str,'0',''),'1',''),'2',''),'3',''),'4',''),'5',''),'6',''),'7',''), '8',''),'9',''),'/',''),' ','+'))) --replace space with a + to avoid empty string
PRINT ''
GO

DECLARE @str varchar(10)
SET @str = '12/  /2012'
IF convert(int, substring(@str,4,2)) <= 31 AND convert(int, substring(@str,4,2)) >= 1
    PRINT @str+': Passed Test'
    ELSE PRINT @str+': Failed Test'
GO

DECLARE @str varchar(10)
SET @str = '12/  /2012' 
PRINT 'Number of characters in ' + @str + ' that are not numerals or a slash (0 means the date is valid; all values greater than 0 indicate a problem): ' + convert(varchar(5),len(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(@str,'0',''),'1',''),'2',''),'3',''),'4',''),'5',''),'6',''),'7',''), '8',''),'9',''),'/',''),' ','+'))) --replace space with a + to avoid empty string

Đầu ra:

--Output
--12/10/2012: Passed Test
--Number of characters in 12/10/2012 that are not numerals or a slash (0 means the date is valid; all values greater than 0 indicate a problem): 0

--Msg 245, Level 16, State 1, Line 4
--Conversion failed when converting the varchar value '!0' to data type int.
--Number of characters in 12/!0/2012 that are not numerals or a slash (0 means the date is valid; all values greater than 0 indicate a problem): 1

--12/  /2012: Failed Test
--Number of characters in 12/  /2012 that are not numerals or a slash (0 means the date is valid; all values greater than 0 indicate a problem): 2

2
+ this happens because sql sometimes doesn't recognize dd/mm/yyyy format
+ so we should always check if the input string is a valid date or not and the accordingly convert it to mm/dd/yyyy and so , i have shown below how it can be done, i have created a function to rearrange in mm/dd/yyyy from dd/mm/yyyy

select case when isdate('yourdate')=1 then CAST('yourdate' AS datetime) 
  else (select * from dbo.fn_convertdate(yourdate))

Create function dbo.fn_convertdate( @Stringdate nvarchar(29))
RETURNS @output TABLE(splitdata NVARCHAR(MAX) 
)
Begin
Declare @table table(id int identity(1,1), data varchar(255))
Declare @firstpart nvarchar(255)
Declare @tableout table(id int identity(1,1), data varchar(255))

Declare @Secondpart nvarchar(255)
Declare @Thirdpart nvarchar(255)

declare @date datetime

insert into @table
select * from dbo.fnSplitString(@Stringdate,'/')
select @firstpart=data from @table where id=2
select @Secondpart=data from @table where id=1
select @Thirdpart=data from @table where id=3
set @date=@firstpart+'/'+@Secondpart+'/'+@Thirdpart
insert into @output(splitdata) values(
@date)


return
End

Có một hàng có vấn đề với chuỗi ngày '19610010' (định dạng: YYYYMMDD) gây ra lỗi "Việc chuyển đổi kiểu dữ liệu nvarchar thành kiểu dữ liệu datetime dẫn đến lỗi giá trị nằm ngoài phạm vi". CHỌN CHUYỂN ĐỔI (datetime, 'yourdate') FROM [yourtable] WHERE ISDATE ('yourdate') = 1 đã lưu trong ngày :)
J Pollack

2

Tôi cũng gặp phải sự cố này trong khi tự động chèn ngày cập nhật vào một cột.

Những gì tôi đã làm là tôi đã thay đổi định dạng ngày hệ thống của mình để phù hợp với định dạng ngày của máy chủ SQL. ví dụ: định dạng SQL của tôi là mm / dd / yyyy và định dạng hệ thống của tôi được đặt thành dd / mm / yyyy. Tôi đã thay đổi định dạng hệ thống của mình thành mm / dd / yyyy và lỗi đã biến mất

-kb


2

Như bạn biết đây là vấn đề định dạng của Vương quốc Anh. Bạn có thể thực hiện chuyển đổi ngày gián tiếp bằng cách sử dụng hàm.

CREATE FUNCTION  ChangeDateFormatFromUK
( 
   @DateColumn varchar(10)
)

RETURNS VARCHAR(10)
AS 
 BEGIN
    DECLARE @Year varchar(4), @Month varchar(2), @Day varchar(2), @Result varchar(10)
    SET @Year = (SELECT substring(@DateColumn,7,10))
    SET @Month = (SELECT substring(@DateColumn,4,5)) 
    SET @Day = (SELECT substring(@DateColumn,1,2))
   SET @Result  = @Year  + '/' @Month + '/' +  @Day

 RETURN @Result
END

Để gọi hàm này

SELECT dbo.ChangeDateFormatFromUK([dates]) from table

Chuyển đổi nó bình thường thành datetime

SELECT CONVERT(DATETIME,dbo.ChangeDateFormatFromUK([dates])) from table

Trong trường hợp của bạn, bạn có thể làm

SELECT [dates] from table where CONVERT(DATETIME,dbo.ChangeDateFormatFromUK([dates])) > GetDate()   -- or any date

2

Thử nghiệm cho năm> 2079. Tôi thấy rằng một người dùng đã đánh máy 2106 thay vì 2016 trong năm (10/12/2106) và bùng nổ; vì vậy vào ngày 10/12/2016 tôi đã kiểm tra và nhận thấy SQL Server được chấp nhận đến 2078, bắt đầu phát sinh lỗi đó nếu năm là 2079 trở lên. Tôi chưa thực hiện bất kỳ nghiên cứu nào thêm về loại SQL Server trượt ngày nào.


1

Tôi chỉ đơn giản là chuyển đổi trường varchar mà tôi muốn chuyển đổi thành một bảng mới (với một DateTime được lưu trữ) sang một bố cục tương thích với DateTime trước tiên và sau đó SQL sẽ thực hiện chuyển đổi từ varchar thành DateTime mà không gặp vấn đề gì.

Trong phần bên dưới (không phải bảng đã tạo của tôi với những cái tên đó!) Tôi chỉ cần đặt trường varchar trở thành một kiểu DateTime nếu bạn muốn:

update report1455062507424 
set [Move Time] = substring([Move Time], 7, 4) + '-'+ substring([Move Time], 4, 2) + '-'+ substring([Move Time], 1, 2) + ' ' + 
    substring([Move Time], 12, 5)  

1
Varchar Date Convert to Date and Change the Format

Ngày 12 tháng 11 năm 2016 12:00, ngày 21 tháng 12 năm 2016, ngày 21 tháng 12 năm 2016 Truy vấn này Hoạt động ở trên để thay đổi thành Định dạng dd / MM / yyyy này SELECT [Member_ID],[Name] , Convert(varchar(50),Convert(date,[DOB],103),103) as DOB ,[NICNO],[Relation] FROM [dbo].[tbl_FamilMember]


0

Lỗi này xảy ra với tôi vì tôi đang cố gắng lưu trữ ngày và giờ tối thiểu trong một cột bằng cách sử dụng truy vấn nội tuyến trực tiếp từ mã C #.

Biến ngày đã được đặt thành 01/01/0001 12:00:00 AM trong mã với thực tế là DateTime trong C # được khởi tạo với ngày và giờ này nếu không được đặt theo cách khác. Và ngày ít nhất có thể được phép trong kiểu dữ liệu datetime của MS-SQL 2008 là 1753-01-01 12:00:00 AM.

Tôi đã thay đổi ngày từ mã và đặt nó thành 01/01/1900 và không có lỗi nào được báo cáo thêm.


0

Tôi đã sử dụng ToString () vào một ngày với mm thay vì MM.


0

Chỉ cần đảm bảo rằng Ngày của bạn tương thích hoặc có thể chạy đúng cách trong trình quản lý cơ sở dữ liệu của bạn (ví dụ: SQL Server Management Studio). Ví dụ: hàm DateTime.Now C # không hợp lệ trong máy chủ SQL nghĩa là truy vấn của bạn phải bao gồm các hàm hợp lệ như GETDATE () cho SQL Server.

Sự thay đổi này đã hoạt động hoàn hảo đối với tôi.


0

Nguyên nhân hơi bất thường cho vấn đề này nhưng chỉ trong trường hợp bất kỳ ai cần nó. Mã tôi đang làm việc đang sử dụng:

java.text.DateFormat.getDateTimeInstance()

để có được một định dạng ngày tháng. Kiểu định dạng do lệnh gọi này trả về đã thay đổi từ Java 8 thành Java 9 như được mô tả trong báo cáo lỗi này: https://bugs.openjdk.java.net/browse/JDK-8152154 rõ ràng là định dạng mà nó trả về cho tôi không phù hợp cho cơ sở dữ liệu. Thay vào đó, giải pháp là:

DateTimeFormatter.ISO_LOCAL_DATE_TIME
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.