SQL - Bir varchar veri türünün bir tarih saat veri türüne dönüştürülmesi, aralık dışı bir değerle sonuçlandı


96

Veri türü değerimi 'den' varchare dönüştürmek için bir SQL çalıştırırken aşağıdaki hatayı alıyorum datetime.

Msg 242, Düzey 16, Durum 3, Satır 1 Bir varchar veri türünün tarih saat veri türüne dönüştürülmesi, aralık dışı bir değerle sonuçlandı.

Verileri kontrol ettim ve garip bir şey göremiyorum: Aşağıdaki kontrolleri yaptım ve hiçbir sonuç vermedi

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

Bakmaya değer başka bir şey var mı ve belki bu konuda herhangi bir ipucu veya yardıma değer mi? Altını çizecek gibi görünmüyor.


3
Tarih sütununun veri türü nedir? Bana tablo şemasını ve hatanın meydana geldiği ifadeyi gösterebilir misiniz lütfen?
Spikeh

3
Sağladığınız altı SQL ifadesinden hangisi başarısız?
Mureinik

1
Altı cümlenin hepsi işe yarıyor ve verilerle ilgili hiçbir sorun olmadığını doğruluyor.
user23495

3
geçersiz tarihleri ​​kontrol etmediniz, örneğin 2013-10-31 veya 2013-02-30. Muhtemelen, karşılaştığınız hata bu tür sorunlu tarihlere işaret ediyor
Dalen

2
Merhaba Dalen, bu kontrolü yaptım. Verilerin ayarlanma şekli 31/10/2013, 30/10/2013'tür. İngiltere formatındadır. Bir sütun türünü değiştirmeye çalışırken bunun herhangi bir etkisi olacak mı, olacağını düşünmemiştim.
user23495

Yanıtlar:


90

Aynı problemle bir hafta önce karşılaştım. Sorun, saat dilimi ayarında. Aa / gg / yyyy gibi diğer biçimlerde belirtin (genellikle çalışır).

Tarihin 30/12/2013 olarak belirtilmesi benim için hataya neden oldu. Ancak, bunu aa / gg / yyyy biçiminde belirtmek işe yaradı.

Girişinizi dönüştürmeniz gerekiyorsa, CONVERTyönteme bakmayı deneyebilirsiniz . Sözdizimi

CONVERT(VARCHAR,@your_date_Value,103)

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

Bitiş 103 , tarih-saat formatıdır.

Dönüştürme formatları ve daha fazla okuma için bu bağlantıya bakın. https://www.w3schools.com/sql/func_sqlserver_convert.asp


1
Yardımın için teşekkürler dostum. Bunu dönüştürmeye çalıştım ama hala şansım olmadı. Tablonun bir varchar olmasından veya bunun başarısız olmasına neden olabilecek başka herhangi bir şeyden kaynaklanıyor olabilir mi?
user23495

2
Örnek verilerinizi (tabloda bulunan) göndermeniz çok yararlı olacaktır. Yorumda, yyyy-aa-gg formatında istediğinizi söylediniz. Öyleyse, bunu dene SELECT CONVERT(char(10), GetDate(),126). GETDATE () 'i gerekli değerle değiştirmeniz yeterlidir .
Mahe

61

Aptalca bir hata yüzünden bu konuyla karşılaştım. Tarihin gerçekten mevcut olduğundan emin olun!

Örneğin:

31 Eylül 2015 mevcut değil.

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

Yani bu mesajla başarısız oluyor:

Error converting data type varchar to datetime.

Düzeltmek için geçerli bir tarih girin:

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

Ve gayet iyi çalışıyor.


2
Evet, çalışmam gereken veritabanında 29 Şubat 2015 son kullanma tarihini buldum. Oraya nasıl girdiğini merak ediyorum. Orada daha kaç tane olduğunu merak ediyorum ...
Kaynak

4
Sadece cast kullandım (tamsayı olarak SUBSTRING ([MyDateField], 1,2))> 31 ve Aralık'ın 60'ı ile bir rekor buldu. Bu eşyaya kim giriyor, Dr Suess?
SteveCav

3
Teşekkürler! Bu benim sorunumdu. Setimde bazı kötü veriler vardı - 01/01/1113, haha.
Sev09

2
Benim için, SQL deyimini oluşturmak için tarihi biçimlendirirken yanlış biçim dizesi koymuştum. Format(DateTime.Now, "yyyymmdd")Gerektiği zaman kullanmıştımFormat(DateTime.Now, "yyyyMMdd")
Jay Imerman

1
Argh Amerikan tarih kuralları! Bir süredir şaşırmıştım, "26 Ekim 2017" den beri, yani '26-10-2017 'mükemmel bir tarih :)
Antimony

31

Son zamanlarda benzer bir sorun yaşadım. Bölgesel ayarlar, hem uygulama hem de veritabanı sunucusunda doğru şekilde ayarlandı. Ancak, SQL yürütmesi sonuçlandı

"Bir varchar veri türünün tarih saat veri türüne dönüştürülmesi, aralık dışı bir değerle sonuçlandı".

Sorun, db kullanıcısının varsayılan diliydi.

Bunu SSMS'de kontrol etmek veya değiştirmek için Güvenlik -> Oturum Açma'ya gidin ve sorguları çalıştıran kullanıcının kullanıcı adını sağ tıklayın. Özellikleri seçin -> genel ve iletişim kutusunun altındaki varsayılan dilin beklediğiniz gibi olduğundan emin olun.

Sorgu çalıştıran tüm kullanıcılar için bunu tekrarlayın.


2
Bu bana yardımcı oldu. Sadece küçük bir düzeltme: varsayılan dil server logindeğil db user. top-password.com/blog/…
Baz Guvenkaya

1
O programın kodunda belirlenen ve ben koduna erişim yoktu, ben onu değiştirdi Englishetmek British Englishve işe yaradı!
vaheeds

1
Benim için de İngiliz İngilizcesini İngiliz İngilizcesine çevirmek - Ali, sen bir hayat kurtarıcısın!
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
Lütfen cevabınıza daha fazla açıklama ekleyin. Soru soran kişinin cevabınızı daha fazla anlamasına yardımcı olacaktır.
Pramod S. Nikam

2

Aynı sorunu yaşadım ve bu sorunun, SQL Server'ın aynı şekilde tamsayılara dönüştürülen karakterlerde karşılaştırma yapmaması nedeniyle ortaya çıktığını belirledim. Testimde, ünlem işareti gibi dönüştürülen karakterlerin bazı karşılaştırmalarının tür dönüştürme hataları döndüreceğini ve boşluk gibi dönüştürülen karakterlerin diğer karşılaştırmalarının aralık dışı olarak belirleneceğini buldum.

Bu örnek kod, farklı olası senaryoları test eder ve iç içe geçmiş REPLACE ifadelerini kullanarak bir çözüm sunar. DEĞİŞTİR, dizede sayı veya eğik çizgi olmayan herhangi bir karakter olup olmadığını belirler ve varsa, dizenin uzunluğunun sıfırdan büyük olacağını ve böylece 'kötü' karakterlerin olduğunu ve tarihin geçersiz olduğunu belirtir. .

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

Çıktı:

--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' (biçim: YYYYAAGG) tarih dizesine sahip sorunlu bir satır vardı, bu da 'nvarchar veri türünün tarih saat veri türüne dönüştürülmesi aralık dışı değer hatasıyla sonuçlandı. [Yourtable] WHERE IsDate ( 'yourdate') SELECT DÖNÜùTÜR (tarih saat, 'yourdate') 1 gün :) kaydedilen =
J Pollack

2

Bir sütuna otomatik olarak bir sysdate eklerken ben de bu sorunla karşılaştım.

Yaptığım şey, sistem tarih formatımı SQL sunucusunun tarih formatıyla eşleşecek şekilde değiştirdim. Örneğin, benim SQL formatım aa / gg / yyyy idi ve sistem formatım gg / aa / yyyy olarak ayarlandı. Sistem formatımı aa / gg / yyyy olarak değiştirdim ve hata gitti

-kb


2

Bildiğiniz gibi, bu İngiltere format sorunu. Fonksiyonu kullanarak dolaylı olarak tarih dönüşümü yapabilirsiniz.

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

Bu işlevi çağırmak için

SELECT dbo.ChangeDateFormatFromUK([dates]) from table

Normalde tarih saatine dönüştür

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

Senin durumunda yapabilirsin

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

2

Yıl> 2079 için test edin. Bir kullanıcının (10/12/2106) yılında 2016 yerine 2106 yazım hatası yaptığını ve patlama olduğunu buldum; 10/12/2016 tarihinde test ettim ve SQL Server'ın 2078'e kadar kabul edildiğini gördüm, yıl 2079 veya daha yüksekse bu hatayı vermeye başladım. SQL Server'ın ne tür bir tarih kayması yaptığı konusunda daha fazla araştırma yapmadım.


1

Önce yeni bir tabloya (bir DateTime dosyalanmış) dönüştürmek istediğim varchar alanını önce DateTime uyumlu bir düzene dönüştürdüm ve sonra SQL, varchar'dan DateTime'a sorunsuz bir şekilde dönüştürme yapacaktır.

Aşağıda (bu adlarla oluşturduğum tablodan değil!), Eğer isterseniz, varchar alanını DateTime'a benzeyecek şekilde yapıyorum:

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 Kasım 2016 12:00, 21/12/2016, 21-12-2016 Bu Sorgu yukarıda bu Biçime geçmek için çalışır. Gg / AA / yyyy SELECT [Member_ID],[Name] , Convert(varchar(50),Convert(date,[DOB],103),103) as DOB ,[NICNO],[Relation] FROM [dbo].[tbl_FamilMember]


0

Bu hata benim için oluştu çünkü minimum tarih ve saati doğrudan C # kodundan satır içi sorguları kullanarak bir sütunda saklamaya çalışıyordum.

Tarih değişkeni, başka şekilde ayarlanmadıysa, C # 'da DateTime'ın bu tarih ve saatle başlatıldığı gerçeği göz önüne alındığında kodda 01/01/0001 12:00:00 AM olarak ayarlandı. Ve MS-SQL 2008 tarih saat veri türünde izin verilen en az olası tarih 1753-01-01 12:00:00 AM'dir.

Tarihi koddan değiştirdim ve 01/01/1900 olarak ayarladım ve daha fazla hata bildirilmedi.


0

MM yerine mm olan bir tarihte ToString () kullandım.


0

Sadece Tarihlerinizin uyumlu olduğundan veya veritabanı yöneticinizde düzgün şekilde çalıştırılabildiğinden emin olun (örn. SQL Server Management Studio). Örneğin, DateTime.Now C # işlevi SQL sunucusunda geçersizdir, yani sorgunuzun SQL Server için GETDATE () gibi geçerli işlevleri içermesi gerekir.

Bu değişiklik benim için mükemmel çalıştı.


0

Bu sorun için biraz alışılmadık bir neden, ancak herhangi birinin ihtiyacı olması durumunda. Üzerinde çalıştığım kod kullanıyordu:

java.text.DateFormat.getDateTimeInstance()

bir tarih formatlayıcı almak için. Bu çağrı tarafından döndürülen biçimlendirme modeli, bu hata raporunda açıklandığı gibi Java 8'den Java 9'a değiştirildi: https://bugs.openjdk.java.net/browse/JDK-8152154 görünüşe göre benim için döndürdüğü biçimlendirme uygun değildi veritabanı için. Bunun yerine çözüm şuydu:

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