Herkese Selam,
Bu yazıda ADD_MONTHS fonksiyonunu kullanırken dikkat edilmesi gereken küçük bir ayrıntıdan kısaca bahsedeceğim umarım farkındalık anlamında faydalı olur.
Bilindiği üzere ADD_MONTHS fonksiyonu parametre olarak verdiğimiz tarihi referans alarak yine verdiğimiz parametre kadar verdiğimiz tarihi ay olarak öteleyen/gerileten sık kullanılan bir SQL fonksiyonu. Kısaca nasıl çalıştığını bir iki örnek ile hatırlayalım.
SELECT add_months(to_date('15.01.2016','DD.MM.YYYY'), 1) ndt FROM dual; NDT ------------------- 15/02/2016 00:00:00 SELECT add_months(to_date('15.01.2016','DD.MM.YYYY'), -1) ndt FROM dual; NDT ------------------- 15/12/2015 00:00:00 SELECT add_months(to_date('15.01.2016','DD.MM.YYYY'), 4) ndt FROM dual; NDT ------------------- 15/05/2016 00:00:00
Amacım bu fonksiyon kullanımını uzun uza diye anlatmak değil. Hedefim bu fonksiyonun eksepsiyonel bir davranışını göstererek farkındalığı arttırmak.
ADD_MONTHS fonksiyonu ile ayın son günleri üzerinde işlem yapmaya çalıştığımızda ADD_MONTHS beklediğiniz gibi çalışmayabiliyor. Bu durumu bir örnek ile açıklayacak olursak;
Bugün günlerden 30.11.2017 olsun ve ben ADD_MONTHS fonksiyonu ile tam 1 ay sonraya yani 30.12.2017 ye gitmek istiyim. En basit mantık ile parametre olarak tarih ile beraber 1 değerini verdiğimde 30.12.2017 tarihine gideceğimi düşünüyorum ve arka tarafta business’ımı buna göre düzenliyorum. Ancak kodu çalıştırdığımda doğru sonuçlar alamadığımı görüyorum. Sebebinin neden kaynaklandığını incelediğimde ADD_MONTHS fonskiyonunun beklendiğimden farklı çalıştığını görüyorum. Şimdi nasıl çalıştığına bakalım.
SELECT add_months(to_date('30.11.2017','DD.MM.YYYY'), 1) ndt FROM dual; NDT ------------------- 31/12/2017 00:00:00
Evet gördüğümüz üzere fonksiyon beklediğimiz üzere ayın 30’una gideceğini beklerken ayın 31’ine gitti. Bunun nedenini araştırdığımda Oracle dokümantasyonunda; ay sonu tarihler ile çalıştığımızda fonksiyon sonucunda üretilen sonuçların yine ay sonu tarihler olacağı bilgisini gördüm. Bu duruma ek olarak eğer sonuçta dönecek ay, parametre olarak verilen tarihin ay parametresinden daha az gün içeriyorsa yine sonuç ilgili ayın son günü olarak gerçekleşecek.
SELECT add_months(to_date('30.01.2017','DD.MM.YYYY'), 1) ndt FROM dual; NDT ------------------- 28/02/2017 00:00:00
Bu durumlardan hareketle ADD_MONTHS fonksiyonu ile ay sonuna denk gelen tarihler ile çalıştığımızda fonksiyonun bu şekilde davrandığını unutmamak gerekiyor. Aksi takdirde sebebinin neden kaynaklandığını anlayabilmek için saatler harcayacağınız problemleriniz oluşabilir.