Problemimize konu olan db tablomuz aşağıdaki gibi:
İçindeki örnek datalar da aşağıdaki gibi:
CREATE TABLE T_CHAT_UPDATE_LOOKUP ( ID NUMBER, OPERATOR_NAME VARCHAR2(100 BYTE) NOT NULL, SCENARIO_LIST VARCHAR2(1000 BYTE) NOT NULL, OG_ROUTE_LIST VARCHAR2(1000 BYTE) NOT NULL, START_DATE DATE NOT NULL, END_DATE DATE DEFAULT to_date('31.12.9999','dd.mm.yyyy'), CREATED_DATE DATE DEFAULT SYSDATE, CREATED_BY VARCHAR2(50 CHAR) DEFAULT USER NOT NULL, MODIFIED_DATE DATE, MODIFIED_BY VARCHAR2(50 CHAR) );
Aşağıdaki fonksiyonumuzla, verilen tarih aralığında geçerli olan, parametre sayısı bulunmak istenmekte:
create or replace function get_count(start_date varchar2, end_date varchar2) return number is l_count number; begin select count(*) into l_count from T_CHAT_UPDATE_LOOKUP c where c.start_date <= TO_DATE(start_date, 'yymmdd') and nvl(c.end_date, to_date('991231', 'yymmdd')) >= TO_DATE(end_date, 'yymmdd'); return l_count; end;
Bu fonksiyon aşağıdaki gibi çalıştırılmak istendiğinde:
declare l_result number; begin l_result := get_count('150501','150501'); dbms_output.put_line(l_result); end;
Şu hata alınmakta:
Buradaki sorunun to_date
çevrimlerinden kaynaklandığı anlaşılmaktadır.
Peki start_date ve end_date
parametreleri to_date fonksiyonunun beklediği varchar2 tipinde sayısal karakterlerden oluşuyor iken ve sorgudan
önce hiçbir şekilde değişikliğe uğratılmadığına göre, yukarıdaki hatayı neden
alırız?
1.
create or replace function get_count(start_date varchar2, end_date varchar2) return number is l_count number; begin select count(*) into l_count from T_CHAT_UPDATE_LOOKUP c; --where c.start_date <= TO_DATE(start_date, 'yymmdd') -- and nvl(c.end_date, to_date('991231', 'yymmdd')) >= TO_DATE(end_date, 'yymmdd'); return l_count; end;
2.
create or replace function get_count(start_date varchar2, end_date varchar2) return number is l_count number; begin select count(*) into l_count from T_CHAT_UPDATE_LOOKUP c where c.start_date <= TO_DATE('150501', 'yymmdd') and nvl(c.end_date, to_date('991231', 'yymmdd')) >= TO_DATE('150501', 'yymmdd'); return l_count; end;
Bu hata ile ilgil biraz düşündükten sonra, aşağıdaki çözümü inceleyebilirsiniz.
Çözüm:
Aslında basit olan bu problemin nedenini şöyle açıklayabiliriz:
Aşağıdaki “get_count”
fonksiyonumuzun içindeki sorguda kullanılan varchar2 “start_date” ve “end_date”
parametrelerinin, algısal olarak, date’e çevrilip sorguda
kullanılması gerektiğini düşünürüz.
Ama gerçekte, sorgu bu şekilde
gerçekleşmemektedir.
Gerçekte olan ise, sorguda önce
date tipindeki “start_date” ve “end_date” kolonları yine date’e
çevrilmeye çalışılmaktadır.
Çözüm olarak ise, “get_count” fonksiyonunda aşağıdaki değişiklikleri
yapmamız gerekir.
Aslında baştan bu fonksiyonu
yazarken, belki de pek önemsenmeyen, yazılım standartlarındaki isimlendirme
kurallarına/standartlarına(naming conventions) göre kod yazmaya çalışsak, bu
problemlerle karşılaşmaz ve çözümünde de gereksiz zaman harcamazdık.
create or replace function get_count(p_start_date varchar2, p_end_date varchar2) return number is l_count number; begin select count(*) into l_count from T_CHAT_UPDATE_LOOKUP c where c.start_date <= TO_DATE(p_start_date, 'yymmdd') and nvl(c.end_date, to_date('991231', 'yymmdd')) >= TO_DATE(p_end_date, 'yymmdd'); return l_count; end;
Bu vesileyle değişken isimlendirme ile ilgili aşağıdaki bağlantıları da paylaşmak isterim:
Oracle Naming Conventions - http://oracle-base.com/articles/misc/naming-conventions.php
Variables Best Practices -
Naming Conventions - http://www.toadworld.com/platforms/oracle/w/wiki/4844.variables-best-practices-naming-conventions.aspx
Java Kod İsimlendirme ve Şekil
(Format) Standardı - http://www.javaturk.org/?p=3180
Kaliteli Java Kodu Nasıl
Yazılır? ya da Kaliteli Kodun Temel İlkeleri - http://www.javaturk.org/?p=3231
Hiç yorum yok:
Yorum Gönder