问题

  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('', 
    (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
";

  效率过低,忽略。

源码

 package test.jdbc;

 import java.sql.*;

 /**
* Created by zhengbin06 on 16/9/14.
*/
public class DataBaseTest {
public static Connection getConnection() throws SQLException,
java.lang.ClassNotFoundException {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/poi_test?jdbcCompliantTruncation=true";
// String url = "jdbc:mysql://localhost:3306/poi_test?jdbcCompliantTruncation=false";
String username = "root";
String password = "";
Connection con = DriverManager.getConnection(url, username, password);
return con;
} public static void main(String args[]) {
try {
Connection con = getConnection();
Statement sql_statement = con.createStatement(); // String query = "select * from wm_poi_dispatch_setting";
String query = "select @@session.sql_mode;";
// 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";
// sql_statement.executeUpdate(update);
ResultSet result = sql_statement.executeQuery(query); // System.out.println("Student表中的数据如下:");
// System.out.println("------------------------");
// System.out.println("wm_poi_id" + " " + "logistics_id" + " " + "value" + " " + "diff");
// System.out.println("------------------------"); // while (result.next()) {
// int wm_poi_id = result.getInt("wm_poi_id");
// int logistics_id = result.getInt("logistics_id");
// int value = result.getInt("value");
// String diff = result.getString("diff");
// System.out.println(" " + wm_poi_id + " " + logistics_id + " " + value + " " + diff);
// }
System.out.println("|@@session.sql_mode|");
while(result.next()) {
String sql_mode = result.getString("@@session.sql_mode");
System.out.println(sql_mode);
}
sql_statement.close();
con.close();
} catch (java.lang.ClassNotFoundException e) {
System.err.print("ClassNotFoundException");
System.err.println(e.getMessage());
} catch (SQLException ex) {
System.err.println("SQLException: " + ex.getMessage());
}
}
}

JDBC插入数据超长时无法自动截断问题的更多相关文章

  1. JDBC插入数据时中文变为问号的解决方法

    JDBC插入数据时中文变为问号的解决方法 制作人:全心全意 出现中文变问号的代码: String url = "jdbc:mysql://localhost:3306/test"; ...

  2. 当插入数据失败时,防止mysql自增长字段的自增长的方法

    问题描述: 当mysql设置了自增长字段时(注意:一个表中只能设置一个自增长字段,可以不是主键,但必须是键 ),如果插入数据失败,那么自增长字段仍然会占用这个自增长值,再次成功插入数据时就会造成断层. ...

  3. 【转】在Spring中基于JDBC进行数据访问时怎么控制超时

    http://www.myexception.cn/database/1651797.html 在Spring中基于JDBC进行数据访问时如何控制超时 超时分类 超时根据作用域可做如下层级划分: Tr ...

  4. 在ES批量插入数据超时时自动重试

    当我们使用ES批量插入数据的时候,一般会这样写代码: from elasticsearch import Elasticsearch,helpers es =Elasticsearch(hosts=[ ...

  5. JDBC插入数据实例

    在本教程将演示如何在JDBC应用程序中向数据库的一个表中插入数据记录. 在执行以下示例之前,请确保您已经准备好以下操作: 具有数据库管理员权限,以在给定模式中数据库表中插入数据记录. 要执行以下示例, ...

  6. Spring JDBC插入数据

    以下示例将展示如何使用Spring jdbc进行插入查询.将向student表中插入几条记录. 语法: String insertQuery = "insert into student ( ...

  7. Dynamic CRM一对多关系的数据删除时设置自动删除关联的数据

    在业务实体中主子表非常常见,然后子表可能有会有自己的子表或者多对多关系,在删除的业务场景下,删除主数据,剩余的子数据就成了脏数据, 之前的做法是,监听主表的删除事件,然后在插件中找到其下的子表数据然后 ...

  8. 使用JDBC插入数据到ORACLE,使用标识列自增列

    不同于SQL Server的是,Oracle中插入数据的时候,没有自增列或者是标识列,但是,我们又不想显式的进行主键的插入,这里,必须在Oracle数据库中指定一个标识列,或者说是一个序列.具体方法如 ...

  9. Oracle通过JDBC插入数据时,自增ID如何自动增长

    一.通过触发器的方式 CREATE OR REPLACE TRIGGER tg_test BEFORE INSERT ON Userinfo FOR EACH ROW WHEN (new.userNo ...

随机推荐

  1. android View未渲染时获得高度

    ViewTreeObserver vto = tv.getViewTreeObserver(); vto.addOnGlobalLayoutListener(new OnGlobalLayoutLis ...

  2. iOS runtime执行时具体解释

    什么是runtime? runtime直译就是执行时间,run(跑,执行) time(时间),网上大家都叫它执行时,它是一套比較底层的纯C语言API,属于一个C语言库,包括了非常多底层的C语言API, ...

  3. CentOS 7.3 系统安装配置图解教程

    一.安装CentOS 7.3 CentOS 7.x系列只有64位系统,没有32位.生产服务器建议安装CentOS-7-x86_64-Minimal-1611.iso版本 成功引导系统后,会出现下面的界 ...

  4. Python 文件 truncate() 方法

    概述 Python 文件 truncate() 方法用于截断文件并返回截断的字节长度. 指定长度的话,就从文件的开头开始截断指定长度,其余内容删除:不指定长度的话,就从文件开头开始截断到当前位置,其余 ...

  5. 基于Android平台的会议室管理系统具体设计说明书

    会议室管理系统具体设计说明书 第一部分  引言 1.编写目的 本说明对会议室管理系统项目的各模块.页面.脚本分别进行了实现层面上的要求和说明. 软件开发小组的产品实现成员应该阅读和參考本说明进行代码的 ...

  6. Sql 查询当天、本周、本月记录

    --查询当天: select * from info where DateDiff(dd,datetime,getdate())=0 --查询24小时内的: select * from info wh ...

  7. 人民币金额转化汉字的java写法

    最近看到一个把一个浮点数转化为汉字人民币的小题,感觉很有意思就去用java实现了一下,没想到没有想得那么简单,在网上搜了一下也不近人意,经过几次修改后,现在实现了,现在分享一下. 一.当输入一个浮点数 ...

  8. 开发前奏曲之添加Android SDK平台工具

    原文:http://android.eoe.cn/topic/android_sdk Android SDK分离不同部位的SDK成单独的下载包.您已经安装只包含SDK工具的SDK入门包.要开发一个An ...

  9. Android基础知识之String类使用详解

    原文:http://android.eoe.cn/topic/android_sdk 字符串资源为你的应用程序提供了可以选择的文本样式和格式的文本.这里有三种类型的资源可以为你的应用程序提供字符串. ...

  10. Android入门-新手如何成功创建一个Android小应用

    原文:http://android.eoe.cn/topic/summary 第一课程:Building Your First App [本课内容简介]欢迎加入到安卓应用的开发大潮中!这门课程会教授你 ...