SQL - Konversi tipe data varchar ke tipe data datetime menghasilkan nilai di luar rentang

96

Saya telah mendapatkan kesalahan berikut saat menjalankan SQL untuk mengonversi nilai tipe data saya dari varcharmenjadi datetime.

Psn 242, Level 16, Status 3, Baris 1 Konversi tipe data varchar ke tipe data datetime menghasilkan nilai di luar rentang.

Saya telah memeriksa data dan tidak dapat melihat apa pun menjadi aneh: Menjalankan pemeriksaan berikut dan semua tidak mengembalikan hasil

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

Apakah ada hal lain yang perlu diperhatikan dan mungkin berharga untuk mendapatkan petunjuk atau bantuan terkait masalah ini? Sepertinya tidak bisa mengerti.

pengguna23495
sumber
3
Apa tipe data dari kolom tanggal? Bisakah Anda menunjukkan skema tabel, dan pernyataan bahwa kesalahan terjadi?
Spikeh
3
manakah dari enam pernyataan SQL yang Anda berikan yang gagal?
Mureinik
1
Enam pernyataan tersebut semuanya bekerja dan memverifikasi tidak ada masalah dengan data.
pengguna23495
3
Anda belum memeriksa tanggal yang tidak valid misalnya 2013-10-31 atau 2013-02-30. Mungkin, kesalahan yang Anda hadapi, mengacu pada tanggal bermasalah semacam itu
Dalen
2
Hai Dalen, saya sudah melakukan pemeriksaan ini. Cara penyiapan data adalah 31/10/2013, 30/10/2013. Itu dalam format Inggris. Apakah ini akan berdampak saat mencoba mengubah jenis kolom, saya tidak berpikir itu akan terjadi.
pengguna23495

Jawaban:

90

Saya menghadapi masalah yang sama seminggu yang lalu. Masalahnya ada pada pengaturan zona waktu. Tentukan dalam format lain seperti bb / hh / tttt (biasanya berfungsi).

Menentukan tanggal sebagai 30/12/2013 mengakibatkan kesalahan bagi saya. Namun, menetapkannya sebagai format bb / hh / tttt berfungsi.

Jika Anda perlu mengubah masukan Anda, Anda dapat mencoba melihat ke dalam CONVERTmetode. Sintaksnya adalah

CONVERT(VARCHAR,@your_date_Value,103)

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

Finishing 103 adalah format tanggal waktu.

Lihat tautan ini untuk format konversi dan bacaan lebih lanjut. https://www.w3schools.com/sql/func_sqlserver_convert.asp

Mahe
sumber
1
Terima kasih atas bantuannya sobat. Saya mencoba untuk mengubah ini tetapi masih tidak berhasil. Mungkinkah karena tabel masih varchar atau apa pun yang dapat menyebabkan ini gagal?
pengguna23495
2
Akan sangat membantu jika Anda memposting data sampel Anda (yang ada di tabel). Dalam komentar Anda mengatakan Anda menginginkannya dalam format tttt-bb-hh. Jadi, coba ini SELECT CONVERT(char(10), GetDate(),126). Cukup ganti GETDATE () dengan nilai yang diperlukan.
Mahe
61

Saya mengalami masalah ini karena kesalahan konyol. Pastikan tanggalnya benar-benar ada!

Sebagai contoh:

31 September 2015 tidak ada.

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

Jadi ini gagal dengan pesan:

Error converting data type varchar to datetime.

Untuk memperbaikinya, masukkan tanggal yang valid:

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

Dan itu berjalan dengan baik.

Tuan C
sumber
2
Ya, saya baru saja menemukan tanggal kedaluwarsa 29 Februari 2015 di database yang harus saya tangani. Saya bertanya-tanya bagaimana itu bisa ada di sana. Saya bertanya-tanya berapa banyak lagi yang ada di sana ...
Sumber daya
4
Baru saja menggunakan cast (SUBSTRING ([MyDateField], 1,2) sebagai integer)> 31 dan menemukan rekor dengan tanggal 60 Desember. Siapa yang memasukkan ini, Dr Suess?
SteveCav
3
Terima kasih! Ini adalah masalahku. Saya memiliki beberapa data buruk di set saya - 01/01/1113, haha.
Sev09
2
Bagi saya, saya telah meletakkan string format yang salah saat memformat tanggal untuk membuat pernyataan SQL. Saya telah digunakan Format(DateTime.Now, "yyyymmdd")ketika seharusnyaFormat(DateTime.Now, "yyyyMMdd")
Jay Imerman
1
Konvensi kencan Argh Amerika! Apakah saya bingung untuk sementara waktu, karena "26 Oktober 2017" yaitu, '26 -10-2017 'adalah tanggal yang valid :)
Antimony
31

Saya mengalami masalah serupa baru-baru ini. Pengaturan regional diatur dengan benar baik di aplikasi dan server database. Namun, eksekusi SQL menghasilkan

"Konversi tipe data varchar ke tipe data datetime menghasilkan nilai di luar rentang".

Masalahnya adalah bahasa default dari pengguna db.

Untuk memeriksa atau mengubahnya di SSMS, buka Keamanan -> Masuk dan klik kanan nama pengguna pengguna yang menjalankan kueri. Pilih properti -> umum dan pastikan bahasa default di bagian bawah dialog adalah yang Anda harapkan.

Ulangi ini untuk semua pengguna yang menjalankan kueri.

ali
sumber
2
Ini membantu saya. Hanya koreksi kecil: bahasa default server logintidak db user. top-password.com/blog/…
Baz Guvenkaya
1
Karena itu diatur dalam kode program dan saya tidak memiliki akses ke kode, saya mengubahnya dari Englishmenjadi British Englishdan berhasil!
vaheeds
1
Sama bagi saya untuk mengubah bahasa Inggris ke bahasa Inggris British - Ali, Anda adalah penyelamat!
david-giorgi
10

Anda bisa memanfaatkan

Set dateformat <date-format> ;

dalam Anda fungsi sp atau prosedur tersimpan untuk menyelesaikan sesuatu.

Sachin Mishra
sumber
1
Ini memecahkan masalah saya. Yang tidak saya mengerti adalah mengapa ini mulai terjadi secara tiba-tiba :(
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)))
sonu yadav
sumber
5
Harap tambahkan lebih banyak deskripsi untuk jawaban Anda. Ini akan membantu penanya dalam memahami lebih banyak dari jawaban Anda.
Pramod S. Nikam
2

Saya memiliki masalah yang sama dan memutuskan bahwa masalah ini muncul karena SQL Server tidak melakukan perbandingan pada karakter yang diubah menjadi bilangan bulat dengan cara yang identik. Dalam pengujian saya, saya telah menemukan bahwa beberapa perbandingan karakter yang dikonversi, seperti tanda seru, akan mengembalikan kesalahan jenis konversi, sementara perbandingan lain dari karakter yang dikonversi, seperti spasi, akan ditentukan berada di luar jangkauan.

Kode contoh ini menguji berbagai kemungkinan skenario dan menyajikan solusi menggunakan pernyataan REPLACE bertingkat. REPLACE menentukan jika ada karakter dalam string yang bukan angka atau garis miring, dan, jika ada, panjang string akan lebih besar dari nol, sehingga menunjukkan bahwa ada karakter 'buruk' dan tanggal tidak valid .

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

Keluaran:

--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
RSax
sumber
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
shashank m
sumber
Memiliki baris bermasalah dengan string tanggal '19610010' (format: YYYYMMDD) yang menyebabkan 'Konversi jenis data nvarchar ke jenis data waktu tanggal menghasilkan kesalahan nilai di luar rentang'. PILIH CONVERT (datetime, 'yourdate') FROM [yourtable] WHERE ISDATE ('yourdate') = 1 disimpan hari :)
J Pollack
2

Saya juga mengalami masalah ini saat memasukkan sysdate secara otomatis ke kolom.

Apa yang saya lakukan adalah mengubah format tanggal sistem saya agar sesuai dengan format tanggal SQL server. misalnya format SQL saya adalah bb / hh / tttt dan format sistem saya disetel ke dd / mm / tttt. Saya mengubah format sistem saya menjadi bb / hh / tttt dan kesalahan hilang

-kb

pengguna5714464
sumber
2

Seperti yang Anda ketahui, ini adalah masalah format UK. Anda dapat melakukan konversi tanggal secara tidak langsung dengan menggunakan fungsi.

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

Untuk memanggil fungsi ini

SELECT dbo.ChangeDateFormatFromUK([dates]) from table

Konversikan secara normal ke datetime

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

Dalam Kasus Anda, Anda dapat melakukannya

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

Tes untuk tahun> 2079. Saya menemukan bahwa pengguna salah ketik 2106, bukan 2016 di tahun (10/12/2106) dan boom; jadi pada 10/12/2016 saya menguji dan menemukan SQL Server diterima hingga 2078, mulai melemparkan kesalahan itu jika tahun 2079 atau lebih tinggi. Saya belum melakukan penelitian lebih lanjut tentang jenis geser tanggal SQL Server.

gordon
sumber
1

Saya cukup mengubah bidang varchar yang ingin saya ubah menjadi tabel baru (dengan DateTime diajukan) ke tata letak yang kompatibel dengan DateTime terlebih dahulu dan kemudian SQL akan melakukan konversi dari varchar ke DateTime tanpa masalah.

Di bawah ini (bukan tabel yang saya buat dengan nama-nama itu!) Saya cukup membuat bidang varchar menjadi mirip DateTime jika Anda ingin:

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)  
Andre
sumber
1
Varchar Date Convert to Date and Change the Format

12 Nov 2016 12:00, 21/12/2016, 21-12-2016 Query ini Bekerja untuk di atas untuk mengubah ke Format ini dd / MM / yyyy SELECT [Member_ID],[Name] , Convert(varchar(50),Convert(date,[DOB],103),103) as DOB ,[NICNO],[Relation] FROM [dbo].[tbl_FamilMember]

Khalid
sumber
0

Kesalahan ini terjadi pada saya karena saya mencoba menyimpan tanggal dan waktu minimum dalam kolom menggunakan kueri sebaris langsung dari kode C #.

Variabel tanggal disetel ke 01/01/0001 12:00:00 dalam kode yang diberikan fakta bahwa DateTime di C # diinisialisasi dengan tanggal dan waktu ini jika tidak disetel dengan cara yang sama. Dan tanggal sekecil mungkin yang diizinkan dalam tipe data waktu MS-SQL 2008 adalah 1753-01-01 12:00:00.

Saya mengubah tanggal dari kode dan mengaturnya ke 01/01/1900 dan tidak ada kesalahan yang dilaporkan lebih lanjut.

Imam Talha
sumber
0

Saya menggunakan ToString () pada tanggal dengan mm bukan MM.

L0uis
sumber
0

Pastikan saja Tanggal Anda kompatibel atau dapat dijalankan dengan baik di manajer database Anda (misalnya SQL Server Management Studio). Misalnya, fungsi DateTime.Now C # tidak valid di server SQL yang berarti kueri Anda harus menyertakan fungsi yang valid seperti GETDATE () untuk SQL Server.

Perubahan ini berhasil dengan sempurna bagi saya.

tonderaimuchada
sumber
0

Penyebab yang agak tidak biasa untuk masalah ini tetapi untuk berjaga-jaga jika ada yang membutuhkannya. Kode yang saya kerjakan menggunakan:

java.text.DateFormat.getDateTimeInstance()

untuk mendapatkan formatter tanggal. Pola pemformatan yang dikembalikan oleh panggilan ini diubah dari Java 8 ke Java 9 seperti yang dijelaskan dalam laporan bug ini: https://bugs.openjdk.java.net/browse/JDK-8152154 tampaknya pemformatan yang dikembalikan untuk saya tidak sesuai untuk database. Solusinya adalah ini sebagai gantinya:

DateTimeFormatter.ISO_LOCAL_DATE_TIME
wobblycogs
sumber