一個jdbc(setTimestamp())的bug?

          Posted on 2008-03-26 17:17 bluoy 閱讀(1800) 評論(0)  編輯  收藏
          項目中組員偶然寫了一段垃圾的sql語句,不想卻誤打誤撞的發現了一個jdbc的bug,包括Oracle 10g附帶的版本。

          詳細描述可以參考如下代碼:
             public static void testSetTimestampBug() throws Exception{
                  Calendar calendar = new GregorianCalendar();
                  Date d = calendar.getTime();
                  
                  String sql = "select 1+1 from dual where ?-sysdate<1";         //error sql
                  String sql1 = "select ?-sysdate from dual";                          //no error sql
                  String sql2 = "select 1+1 from dual where ?-1<sysdate";       //no error sql
                  PreparedStatement pst = cn.prepareStatement(sql);
                  //pst.setDate(1, new java.sql.Date(d.getTime()));                 //no  error
                  pst.setTimestamp(1, new java.sql.Timestamp(d.getTime()));   //bug!!!, throw SQLException: ORA-00932
              }
          三種sql的寫法中,第一種寫法在使用setTimestamp()時會出錯,其他倆種卻不會有問題。
          即正常調用PreparedStatement.setTimestamp()方法,遇到某些特殊寫法的sql語句卻會出錯。
          本例中,拋出如下例外:
          java.sql.SQLException: ORA-00932: inconsistent datatypes: expected NUMBER got INTERVAL.
          然而,如果使用setDate()方法,則一切正常,三種寫法都沒有問題。

          因為有這個問題,如果在持久層使用了其他的中間件,則這個問題可能變的更加隱蔽,比如iBatis中的處理是這樣的:
          java.util.Date ---> ibatis.DateTypeHandler----->PreparedStatement.setTimestamp() 
          java.sql.Date ---> ibatis.SqlDateTypeHandler----->PreparedStatement.setDate()
          如果不注意輸入參數類型的話,就會遇到上述問題。我就因此費了不少周折。
          對于iBatis的使用建議,保證入口參數類型始終為java.sql.Date即可。


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 东乌| 河间市| 新化县| 额济纳旗| 芮城县| 旬阳县| 潞城市| 罗定市| 谢通门县| 北宁市| 蓝山县| 常德市| 田阳县| 东方市| 四会市| 汉川市| 平度市| 东港市| 偏关县| 略阳县| 湘潭市| 广丰县| 金乡县| 苏州市| 洛南县| 禹州市| 延庆县| 南雄市| 靖宇县| 留坝县| 辽中县| 洪雅县| 石嘴山市| 旺苍县| 花莲县| 柳林县| 沙洋县| 怀集县| 嘉鱼县| 昌乐县| 云梦县|