JDBC插入數據超長時無法自動截斷問題


問題

  JDBC操作MySQL數據庫,當進行插入或更新操作的數據長度超過表字段的聲明最大長度時,會報出以下錯誤,導致不能正常插入:

SQLException: Data truncation: Data too long for column 'diff' at row 2

  但是當直接在MySQL客戶端操作時,發現確實可以的,只不過會自動對插入的數據進行截斷處理:

  'diff'字段的長度為3,下面插入一個超長的數據'1234':

  可以成功插入,並對數據進行了截斷處理,插入結果為'123',不過MySQL發出了警告(warning)。

  但是到了JDBC就是SQLException了。

解決

  JDBC Driver作為MySQL Client與MySQL Server交互時,JDBC Driver默認會設置會話SQL_MODEL='STRICT_TRANS_TABLES',可以寫一個sql語句:'select @@session.sql_mode;',executeQuery執行以下(詳見最后源碼),默認情況下JDBC的jdbcCompliantTruncation(是否截斷)參數為true,修改為false即可解決。(MySQL本身也可以設置相關的配置,詳見MySQL——SQL Mode詳解

  將JDBC連接的URL改為:

jdbc:mysql://localhost:3306/table_name?jdbcCompliantTruncation=false

  不過這樣會存在另外一個問題,嘗試更新int類型的數據,如果插入數據超長(也就是超過可以裝載的大小),將插入字段的最大值:

  所以最好的解決辦法還是在程序中做判斷+截斷吧!

也算一種解決方法

  問題的產生就是,JDBC並不能對超長的插入字段進行自動截斷處理並順利插入數據,所以如果在SQL中獲得字段的聲明長度,再用MySQL提供的left等截斷函數,也能實現,不過需要子查詢,效率可想而知。

  獲得某庫某表某字段的聲明長度SQL:

  再加上LEFT()函數:

String update = "update wm_poi_dispatch_setting set diff=LEFT('4567', 
    (select CHARACTER_MAXIMUM_LENGTH FROM INFORMATION_SCHEMA.COLUMNS
    WHERE table_name = 'wm_poi_dispatch_setting' and table_schema = 'poi_test' and column_name = 'diff' limit 0,1)
    ) " +     "where wm_poi_id = 1
";

  效率過低,忽略。

源碼

 1 package test.jdbc;
 2 
 3 import java.sql.*;
 4 
 5 /**
 6  * Created by zhengbin06 on 16/9/14.
 7  */
 8 public class DataBaseTest {
 9     public static Connection getConnection() throws SQLException,
10             java.lang.ClassNotFoundException {
11         Class.forName("com.mysql.jdbc.Driver");
12         String url = "jdbc:mysql://localhost:3306/poi_test?jdbcCompliantTruncation=true";
13 //        String url = "jdbc:mysql://localhost:3306/poi_test?jdbcCompliantTruncation=false";
14         String username = "root";
15         String password = "";
16         Connection con = DriverManager.getConnection(url, username, password);
17         return con;
18     }
19     
20     public static void main(String args[]) {
21         try {
22             Connection con = getConnection();
23             Statement sql_statement = con.createStatement();
24             
25 //            String query = "select * from wm_poi_dispatch_setting";
26             String query = "select @@session.sql_mode;";
27 //            String update = "update wm_poi_dispatch_setting set diff=LEFT('4567', (select CHARACTER_MAXIMUM_LENGTH FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = 'wm_poi_dispatch_setting' and table_schema = 'poi_test' and column_name = 'diff' limit 0,1)) " +
28 //                    "where wm_poi_id = 1";
29 //            sql_statement.executeUpdate(update);
30             ResultSet result = sql_statement.executeQuery(query);
31             
32 //            System.out.println("Student表中的數據如下:");
33 //            System.out.println("------------------------");
34 //            System.out.println("wm_poi_id" + " " + "logistics_id" + " " + "value" + " " + "diff");
35 //            System.out.println("------------------------");
36             
37 //            while (result.next()) {
38 //                int wm_poi_id = result.getInt("wm_poi_id");
39 //                int logistics_id = result.getInt("logistics_id");
40 //                int value = result.getInt("value");
41 //                String diff = result.getString("diff");
42 //                System.out.println(" " + wm_poi_id + " " + logistics_id + " " + value + " " + diff);
43 //            }
44             System.out.println("|@@session.sql_mode|");
45             while(result.next()) {
46                 String sql_mode = result.getString("@@session.sql_mode");
47                 System.out.println(sql_mode);
48             }
49             sql_statement.close();
50             con.close();
51         } catch (java.lang.ClassNotFoundException e) {
52             System.err.print("ClassNotFoundException");
53             System.err.println(e.getMessage());
54         } catch (SQLException ex) {
55             System.err.println("SQLException: " + ex.getMessage());
56         }
57     }
58 }
View Code


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM