一個jdbc(setTimestamp())的bug?

          Posted on 2008-03-26 17:17 bluoy 閱讀(1801) 評論(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即可。


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


          網站導航:
           
          主站蜘蛛池模板: 扎赉特旗| 探索| 浑源县| 廊坊市| 邢台县| 攀枝花市| 东山县| 桂平市| 乐亭县| 乐安县| 建瓯市| 江门市| 铜梁县| 康定县| 澎湖县| 黄陵县| 普安县| 永州市| 南陵县| 广宗县| 彩票| 和平县| 肇东市| 彰化市| 梁平县| 克东县| 修文县| 铁力市| 道孚县| 香港 | 图木舒克市| 偃师市| 天祝| 万年县| 丹棱县| 福海县| 四子王旗| 普陀区| 牡丹江市| 南平市| 桃江县|