SQL - การแปลงชนิดข้อมูล varchar เป็นชนิดข้อมูลวันที่และเวลาส่งผลให้ค่าอยู่นอกช่วง


96

ผมได้รับข้อผิดพลาดต่อไปนี้เมื่อเรียกใช้ SQL เพื่อแปลงค่าชนิดข้อมูลของฉันจากไปvarchardatetime

ข่าวสารเกี่ยวกับ 242 ระดับ 16 สถานะ 3 บรรทัดที่ 1 การแปลงชนิดข้อมูล varchar เป็นชนิดข้อมูลวันที่และเวลาส่งผลให้ค่าอยู่นอกช่วง

ฉันตรวจสอบข้อมูลแล้วและไม่เห็นอะไรแปลก ๆ : เรียกใช้การตรวจสอบต่อไปนี้และไม่มีผลลัพธ์ทั้งหมด

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

มีอะไรที่ควรค่าแก่การดูและอาจคุ้มค่ากับคำแนะนำหรือความช่วยเหลือเกี่ยวกับปัญหานี้หรือไม่? ดูเหมือนจะไม่ถึงจุดสุดยอด


3
ประเภทข้อมูลของคอลัมน์วันที่คืออะไร? คุณช่วยแสดงสคีมาของตารางและข้อความว่าเกิดข้อผิดพลาดได้ไหม
Spikeh

3
หนึ่งในหกคำสั่ง SQL ที่คุณระบุล้มเหลว?
Mureinik

1
คำสั่งทั้งหกใช้งานได้และยืนยันว่าไม่มีปัญหากับข้อมูล
user23495

3
คุณไม่ได้ตรวจสอบวันที่ที่ไม่ถูกต้องเช่น 2013-10-31 หรือ 2013-02-30 อาจเป็นข้อผิดพลาดที่คุณพบหมายถึงวันที่มีปัญหาประเภทนั้น
Dalen

2
สวัสดี Dalen ฉันได้ทำการตรวจสอบนี้แล้ว วิธีตั้งค่าข้อมูลคือ 31/10/2013, 30/10/2013 อยู่ในรูปแบบสหราชอาณาจักร สิ่งนี้จะมีผลกระทบหรือไม่เมื่อพยายามเปลี่ยนประเภทคอลัมน์ไม่คิดว่าจะเป็นเช่นนั้น
user23495

คำตอบ:


90

ฉันประสบปัญหาเดียวกันเมื่อสัปดาห์ก่อน ปัญหาคือการตั้งค่าโซนเวลา ระบุในรูปแบบอื่นเช่น mm / dd / yyyy (โดยปกติจะใช้งานได้)

การระบุวันที่เป็น30/12/2013ทำให้เกิดข้อผิดพลาดสำหรับฉัน อย่างไรก็ตามการระบุเป็นรูปแบบ mm / dd / yyyy ใช้งานได้

หากคุณต้องการแปลงอินพุตของคุณคุณสามารถลองค้นหาCONVERTวิธีการ ไวยากรณ์คือ

CONVERT(VARCHAR,@your_date_Value,103)

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

103 การตกแต่งเป็นรูปแบบวันที่และเวลา

อ้างอิงลิงค์นี้สำหรับรูปแบบการแปลงและการอ่านเพิ่มเติม https://www.w3schools.com/sql/func_sqlserver_convert.asp


1
ขอบคุณสำหรับความช่วยเหลือ ฉันพยายามแปลงสิ่งนี้ แต่ก็ยังไม่มีโชค อาจเป็นเพราะตารางยังคงเป็น varchar หรือสิ่งอื่นใดที่อาจทำให้สิ่งนี้ล้มเหลว?
user23495

2
จะมีประโยชน์มากหากคุณโพสต์ข้อมูลตัวอย่าง (ซึ่งอยู่ในตาราง) ในความคิดเห็นคุณบอกว่าต้องการในรูปแบบ yyyy-mm-dd SELECT CONVERT(char(10), GetDate(),126)ดังนั้นลองนี้ เพียงแค่แทนที่GETDATE ()ด้วยค่าที่จำเป็น
Mahe

61

ฉันพบปัญหานี้เนื่องจากความผิดพลาดโง่ ๆ ให้แน่ใจว่าวันนั้นมีอยู่จริง!

ตัวอย่างเช่น:

31 กันยายน 2015 ไม่มีอยู่จริง

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

จึงล้มเหลวด้วยข้อความ:

Error converting data type varchar to datetime.

ในการแก้ไขให้ป้อนวันที่ที่ถูกต้อง:

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

และดำเนินการได้ดี


2
ใช่ฉันเพิ่งพบวันหมดอายุของวันที่ 29 กุมภาพันธ์ 2015 ในฐานข้อมูลที่ฉันต้องดำเนินการ ฉันสงสัยว่ามันเข้าไปอยู่ในนั้นได้อย่างไร ฉันสงสัยว่ามีอีกกี่คน ...
แหล่งข้อมูล

4
เพิ่งใช้แคสต์ (SUBSTRING ([MyDateField], 1,2) เป็นจำนวนเต็ม)> 31 และพบบันทึกในวันที่ 60 ธันวาคม ใครเป็นคนป้อนสิ่งนี้ Dr Suess?
SteveCav

3
ขอบคุณ! นี่คือปัญหาของฉัน ฉันมีข้อมูลที่ไม่ดีในชุดของฉัน - 01/01/1113 ฮ่าฮ่า
Sev09

2
สำหรับฉันฉันใส่สตริงรูปแบบไม่ถูกต้องเมื่อจัดรูปแบบวันที่เพื่อสร้างคำสั่ง SQL ฉันเคยใช้Format(DateTime.Now, "yyyymmdd")เวลาที่ควรจะเป็นFormat(DateTime.Now, "yyyyMMdd")
Jay Imerman

1
Argh American date conventions! ทำให้ฉันนิ่งงันไปชั่วขณะเนื่องจาก "26 ตุลาคม 2017" คือ "26-10-2017" เป็นวันที่ที่สมบูรณ์แบบ :)
พลวง

31

ฉันมีปัญหาคล้ายกันเมื่อเร็ว ๆ นี้ การตั้งค่าภูมิภาคได้รับการตั้งค่าอย่างเหมาะสมทั้งในแอปและเซิร์ฟเวอร์ฐานข้อมูล อย่างไรก็ตามการดำเนินการของ SQL ส่งผลให้

"การแปลงประเภทข้อมูล varchar เป็นประเภทข้อมูลวันที่และเวลาส่งผลให้มีค่าอยู่นอกช่วง"

ปัญหาคือภาษาเริ่มต้นของผู้ใช้ db

หากต้องการตรวจสอบหรือเปลี่ยนแปลงใน SSMS ให้ไปที่ความปลอดภัย -> การเข้าสู่ระบบและคลิกขวาที่ชื่อผู้ใช้ของผู้ใช้ที่เรียกใช้แบบสอบถาม เลือกคุณสมบัติ -> ทั่วไปและตรวจสอบให้แน่ใจว่าภาษาเริ่มต้นที่ด้านล่างของกล่องโต้ตอบเป็นสิ่งที่คุณคาดหวัง

ทำซ้ำสิ่งนี้สำหรับผู้ใช้ทั้งหมดที่เรียกใช้แบบสอบถาม


2
สิ่งนี้ช่วยฉันได้ เพียงแค่การแก้ไขขนาดเล็ก: ภาษาเริ่มต้นของการไม่ได้server login top-password.com/blog/…db user
Baz Guvenkaya

1
เนื่องจากตั้งค่าในรหัสโปรแกรมและฉันไม่สามารถเข้าถึงรหัสได้ฉันจึงเปลี่ยนจากEnglishเป็นBritish Englishและใช้งานได้!
vaheeds

1
เหมือนกันสำหรับฉันที่จะเปลี่ยนภาษาอังกฤษเป็นภาษาอังกฤษแบบอังกฤษ - อาลีคุณเป็นผู้ช่วยชีวิต!
david-giorgi

10

คุณสามารถใช้ประโยชน์จากไฟล์

Set dateformat <date-format> ;

ในฟังก์ชัน sp ของคุณหรือขั้นตอนการจัดเก็บเพื่อทำงานให้ลุล่วง



1
สิ่งนี้ช่วยแก้ปัญหาของฉันได้ สิ่งที่ฉันไม่เข้าใจคือทำไมสิ่งนี้เริ่มเกิดขึ้นกะทันหัน :(
VictorEspina

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
โปรดเพิ่มคำอธิบายเพิ่มเติมในคำตอบของคุณ จะช่วยให้ผู้ถามเข้าใจคำตอบของคุณได้มากขึ้น
Pramod S. Nikam

2

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

โค้ดตัวอย่างนี้จะทดสอบสถานการณ์ที่เป็นไปได้ต่างๆและนำเสนอวิธีแก้ปัญหาโดยใช้คำสั่ง REPLACE ที่ซ้อนกัน REPLACE กำหนดว่ามีอักขระใด ๆ ในสตริงที่ไม่ใช่ตัวเลขหรือเครื่องหมายทับและหากมีอยู่ความยาวของสตริงจะมากกว่าศูนย์ซึ่งแสดงว่ามีอักขระ 'ไม่ถูกต้อง' และวันที่ไม่ถูกต้อง .

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

เอาท์พุต:

--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

มีแถวที่มีปัญหาซึ่งมีสตริงวันที่ "19610010" (รูปแบบ: YYYYMMDD) ซึ่งทำให้เกิด "การแปลงประเภทข้อมูล nvarchar เป็นประเภทข้อมูลวันที่และเวลาส่งผลให้เกิดข้อผิดพลาดค่าที่อยู่นอกช่วง" เลือก CONVERT (วันที่และเวลา 'yourdate') จาก [yourtable] WHERE ISDATE ('yourdate') = 1 บันทึกวัน :)
J Pollack

2

ฉันพบปัญหานี้เช่นกันในขณะที่แทรก sysdate ลงในคอลัมน์โดยอัตโนมัติ

สิ่งที่ฉันทำคือฉันเปลี่ยนรูปแบบวันที่ระบบของฉันให้ตรงกับรูปแบบวันที่ของเซิร์ฟเวอร์ SQL เช่นรูปแบบ SQL ของฉันคือ mm / dd / yyyy และรูปแบบระบบของฉันถูกตั้งค่าเป็น dd / mm / yyyy ฉันเปลี่ยนรูปแบบระบบเป็น mm / dd / yyyy และข้อผิดพลาดหายไป

-kb


2

ดังที่คุณทราบว่านี่เป็นปัญหารูปแบบของสหราชอาณาจักร คุณสามารถทำการแปลงวันที่ทางอ้อมโดยใช้ฟังก์ชัน

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

เพื่อเรียกใช้ฟังก์ชันนี้

SELECT dbo.ChangeDateFormatFromUK([dates]) from table

แปลงตามปกติเป็นวันที่และเวลา

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

ในกรณีของคุณคุณสามารถทำได้

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

2

ทดสอบสำหรับปี> 2079 ฉันพบว่ามีผู้ใช้พิมพ์ 2106 แทนที่จะเป็น 2016 ในปี (10/12/2106) และบูม ดังนั้นในวันที่ 10/12/2016 ฉันได้ทดสอบและพบว่า SQL Server ยอมรับได้ถึงปี 2078 เริ่มโยนข้อผิดพลาดนั้นหากปี 2079 หรือสูงกว่า ฉันยังไม่ได้ทำการค้นคว้าเพิ่มเติมเกี่ยวกับการเลื่อนวันที่ของ SQL Server แบบใด


1

ฉันเพิ่งแปลงเขตข้อมูล varchar ที่ฉันต้องการแปลงเป็นตารางใหม่ (พร้อมกับ DateTime ที่ยื่น) เป็นรูปแบบที่เข้ากันได้กับ DateTime ก่อนจากนั้น SQL จะทำการแปลงจาก varchar เป็น DateTime โดยไม่มีปัญหา

ในด้านล่าง (ไม่ใช่ตารางที่ฉันสร้างขึ้นด้วยชื่อเหล่านั้น!) ฉันแค่ทำให้ฟิลด์ varchar เป็น DateTime ที่มีลักษณะเหมือนกันหากคุณต้องการ:

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

12 พ.ย. 2559 12:00, 21/12/2559, 21-12-2559 คำค้นหานี้ทำงานสำหรับด้านบนเพื่อเปลี่ยนเป็นรูปแบบนี้ dd / MM / yyyy SELECT [Member_ID],[Name] , Convert(varchar(50),Convert(date,[DOB],103),103) as DOB ,[NICNO],[Relation] FROM [dbo].[tbl_FamilMember]


0

ข้อผิดพลาดนี้เกิดขึ้นสำหรับฉันเนื่องจากฉันพยายามจัดเก็บวันที่และเวลาขั้นต่ำในคอลัมน์โดยใช้การสืบค้นแบบอินไลน์โดยตรงจากรหัส C #

ตัวแปรวันที่ถูกตั้งค่าเป็น 01/01/0001 00:00:00 น. ในรหัสเนื่องจาก DateTime ใน C # เริ่มต้นด้วยวันที่และเวลานี้หากไม่ได้ตั้งค่าอื่น ๆ และวันที่ที่เป็นไปได้น้อยที่สุดที่อนุญาตในประเภทข้อมูลวันและเวลาของ MS-SQL 2008 คือ 1753-01-01 00:00:00 น.

ฉันเปลี่ยนวันที่จากรหัสและตั้งค่าเป็น 01/01/1900 และไม่มีการรายงานข้อผิดพลาดเพิ่มเติม



0

ตรวจสอบให้แน่ใจว่า Dates ของคุณเข้ากันได้หรือสามารถทำงานได้อย่างถูกต้องในตัวจัดการฐานข้อมูลของคุณ (เช่น SQL Server Management Studio) ตัวอย่างเช่นฟังก์ชัน DateTime ตอนนี้ C # ไม่ถูกต้องในเซิร์ฟเวอร์ SQL หมายความว่าแบบสอบถามของคุณต้องรวมฟังก์ชันที่ถูกต้องเช่น GETDATE () สำหรับ SQL Server

การเปลี่ยนแปลงนี้ได้ผลอย่างสมบูรณ์สำหรับฉัน


0

สาเหตุที่ผิดปกติเล็กน้อยสำหรับปัญหานี้ แต่ในกรณีที่ใครก็ตามต้องการ รหัสที่ฉันใช้คือ:

java.text.DateFormat.getDateTimeInstance()

เพื่อรับตัวจัดรูปแบบวันที่ รูปแบบการจัดรูปแบบที่ส่งคืนโดยการเรียกนี้เปลี่ยนจาก Java 8 เป็น Java 9 ตามที่อธิบายไว้ในรายงานข้อบกพร่องนี้: https://bugs.openjdk.java.net/browse/JDK-8152154เห็นได้ชัดว่าการจัดรูปแบบที่ส่งคืนสำหรับฉันไม่เหมาะสม สำหรับฐานข้อมูล วิธีแก้ปัญหาคือแทน:

DateTimeFormatter.ISO_LOCAL_DATE_TIME
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.