Adem KALIN – Yazılım Mühendisi

Hayat Kurtarmayan Bilgiler – 3 : SQL VARCHAR’dan DATETIME’a Çevrim Hatası

Merhaba,

Zamanında, rapor amaçlı olarak SQL ile cebelleşirken, çözümünü bulana kadar anlam veremediğimiz bir sorun ile karşılaşmış ve bütün günümüzü yemişti çözümünü bulmak. Bu yüzden bu konuyu yazmaya karar verdim 🙂

Problemimiz SQL’de VARCHAR tipinde yazılmış bir tarih bilgisini GETDATE() metodu ile karşılaştırma sırasında “dann!..” diye karşıma çıktı. Aynen şöyle yazıyordu : “Conversion failed when converting date and/or time from character string.” Bu mesajı gören herkes gibi öncelikle kayıtları kontrol ettim, gayet normal görünüyordu. Bütün bilgiler olması gerektiği gibi “12.05.2013 00:00:00.000” formatındaydı. He bu arada, “Yahu tarihi neden VARCHAR ’da tutuyorsunuz arkadaş” demeyin, tasarım bazen sizi bu tarz taklalara zorunlu kılabiliyor 🙂 Ama işin daha da ilginci, deneme amaçlı olarak WHERE şartında GETDATE() fonksiyonu yerine aynı alanın DATETIME ‘a dönüştürülmüş herhangi bir halini yazdığımda ise hata almıyordum.

Başladık tırmalamaya artık, bir günün sonunda sebebi bulmuştuk bir tecrübeli arkadaşımızın da katkılarıyla, ancak olan o koca günümüze olmuştu. Çözüm için tarih bilgisini DATETIME ‘a dönüştürürken önce NVARCHAR ‘a dönüştürüp, bu çıkan değeri de daha sonra DATETIME ‘a dönüştürdüğümüzde başarılı olduk. (Aşağıda örneklerini yazdığımda daha anlaşılır olacaktır.) Meğer ki VARCHAR karakter saklama bakımından NVARCHAR ‘a göre biraz daha dar bi skalaya sahipmiş sanırım. (İki veri tipi arasındaki fark için şu şekilde Google ‘a başvurabilirsiniz : Tıkla) En azından bundan kaynaklandığını düşünüyorum.

Şimdi adım adım örneklerle açıklayalım.

Öncelikle DateTimeSampleisimli tablomuzu aşağıdaki yapıda oluşturalım. Tabloda bir VARCHAR bir de NVARCHAR tipinde kolon ekleyelim. (Karşılaştırmalarda hata aldığımız alan VARCHAR tipinde idi, örneğimde bu şekilde kullanacağım, hatırlatmak istedim) :

VarcharToDateTime_1

Daha sonra test kayıtlarımızı insert edelim (Bunu script ile de yapabilirsiniz, ben kolay olması için görsel yaptım) :

VarcharToDateTime_2

Kayıtları insert ederken bir de tarih dışında bilgi içeren kayıt insert edelim. Daha sonra WHERE şartında ID bilgisinden bu kaydı dışarıda tutacağız.

Kayıtları insert ettikten sonra aşağıdaki gibi bir sorgu alabiliriz :

1
SELECT * FROM DateTimeSample (NOLOCK)

VarcharToDateTime_3

Şimdi ilk olarak hata aldığımız sorguyu yazalım (Aşağıdaki hata mesajını örnek olması açısından koydum. Aslında aynı durumu kendi bilgisayarımda oluşturamadım, aynı hatayı alamadım J Belki SQL SERVER 2005 ‘ten kaynaklı da olabilir bu durum, yönetememiş olabilir.) :

1
2
3
4
SELECT *
FROM DateTimeSample(NOLOCK)
WHERE CONVERT(DATETIME,Value1,103) < GETDATE() 
      AND ID <> 4

VarcharToDateTime_4

Sorguyu aşağıdaki şekilde aldığımda da hiçbir hata oluşmuyor :

1
2
3
4
SELECT CONVERT(DATETIME,Value1,103), 
       CONVERT(DATETIME,Value2,103)
FROM DateTimeSample(NOLOCK)
WHERE ID <> 4

VarcharToDateTime_5

Hatta aşağıdaki şekilde yazdığımızda da sorun olmadı. Sorun sadece WHERE şartı içerisinde GETDATE() ile bir karşılaştırma yaptığımızda oluşuyordu :

1
2
3
4
5
SELECT CONVERT(DATETIME,Value1,103), 
       CONVERT(DATETIME,Value2,103)
FROM DateTimeSample(NOLOCK)
WHERE DATEADD(DAY,2,CONVERT(DATETIME,Value1,103)) > CONVERT(DATETIME,Value1,103) 
      AND ID <> 4

VarcharToDateTime_6

Son olarak sorguyu aşağıdaki gibi denediğimizde sorunun çözülmüş olduğunu gördük :

1
2
3
4
5
SELECT CONVERT(DATETIME,Value1,103), 
       CONVERT(DATETIME,Value2,103)
FROM DateTimeSample(NOLOCK)
WHERE CONVERT(DATETIME,SUBSTRING(CONVERT(NVARCHAR(MAX),Value1),1,23),103) < GETDATE() 
      AND ID <> 4

VarcharToDateTime_7

Özet geçersem, SQL SERVER 2005 ortamında çalıştığımız sorgularda, WHERE şartı içerisinde VARCHAR ’dan DATETIME tipine dönüştürerek GETDATE() ile yaptığımız karşılaştırmalarda sorun yaşıyorduk. VARCHAR değeri önce NVARCHAR ‘ a dönüştürerek sorunu aşmış olduk. Belki bir gün birilerinin işine yarar, kim bilir.

CONVERT  fonksiyonunda kullandığım 103 parametresi ve o pararmetrenin yerine alabilecek diğer değerler ve açıklamaları için MSDN sayfasını ziyaret edebilirsiniz : MSDN

NOT : SQL’de daha önce yine DATETIME ile ilgili olarak bir bela ile uğraşmış ve sebebini yazmıştım, okumak isterseniz :

Hayat Kurtarmayan Bilgiler – 1 : Windows’da “Input Languages” Belası

2 thoughts on “Hayat Kurtarmayan Bilgiler – 3 : SQL VARCHAR’dan DATETIME’a Çevrim Hatası

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir