- 浏览: 1278110 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (471)
- Database (29)
- Java (47)
- Frameworks (9)
- JavaScript (30)
- Others (27)
- ExtJS (26)
- Linux (49)
- Windows (11)
- Web (8)
- Ubunt (9)
- Shell (21)
- MySQL (26)
- Redis (9)
- Git (6)
- Maven (29)
- Python (3)
- Nginx (10)
- Nodejs (7)
- Network (1)
- GO (2)
- Docker (36)
- MongoDB (5)
- Intellij idea (7)
- Ruby (3)
- Weblogic (3)
- CSS (15)
- VMware (3)
- Tomcat (6)
- Cache (2)
- PHP (8)
- Mac (7)
- jQuery (3)
- Spring (8)
- HTML5 (2)
- Kubernetes (8)
最新评论
-
masuweng:
Intellij idea 主题下载网址 -
mimicom:
还有一个情况, 也是连不上 2018-05-06T06:01: ...
docker-compose 部署shipyard -
lixuansong:
put()方法调用前必须先手动调用remove(),不然不会实 ...
JavaScript创建Map对象(转) -
jiao_zg22:
方便问下,去哪里下载包含Ext.ux.TabCloseMenu ...
Ext.ux.TabCloseMenu插件的使用(TabPanel右键关闭菜单) 示例 -
netwelfare:
对于基本类型的讲解,文章写的有点简单了,没有系统化,这篇文章介 ...
Java 基础类型范围
PreparedStatement中setString方法的异常(转载)
使用ojdbc14驱动
当执行插入语句到
stmt.setString(2, myString);
的时候,出现如下异常:
java.sql.SQLException: 数据大小超出此类型的最大值
而myString变量的内容为超过700的中文字符(测试的英文字符为2000个)。
也就是说一个中文字符占据了3-4个字节,而且英文字符个数也不对,这好像有点不可思议。
分析原因:
1、驱动程序在把SQL语句发给数据库前,PreparedStatement会对字符串进行预处理并进行转义替换;
2、字符集原因。
通过阅读PreparedStatement文档,发现有一个setCharacterStream方法可以解决这个问题:
stmt.setCharacterStream(2,new InputStreamReader(myString, myString.length());
替换之后中文字符可达1400多。
上次对PreparedStatement的setString中字符串长度这个问题没有解决透彻,
也没有深入分析其中的原因。
现在通过Oracle提供的JDBC文档来详细看看问题的来由。
我们都知道Oracle提供了两种客户端访问方式OCI和thin,
在这两种方式下,字符串转换的过程如下:
1、JDBC OCI driver:
在JDBC文档中是这么说的:
“
If the value of NLS_LANG is set to a character set other than US7ASCII or WE8ISO8859P1, then the driver uses UTF8 as the client character set. This happens automatically and does not require any user intervention. OCI then converts the data from the database character set to UTF8. The JDBC OCI driver then passes the UTF8 data to the JDBC Class Library where the UTF8 data is converted to UTF-16. ”
2、JDBC thin driver:
JDBC文档是这样的:
“If the database character set is neither ASCII (US7ASCII) nor ISO Latin1 (WE8ISO8859P1), then the JDBC thin driver must impose size restrictions for SQL CHAR bind parameters that are more restrictive than normal database size limitations. This is necessary to allow for data expansion during conversion.
The JDBC thin driver checks SQL CHAR bind sizes when a setXXX() method (except for the setCharacterStream() method) is called. If the data size exceeds the size restriction, then the driver returns a SQL exception (SQLException: Data size bigger than max size for this type) from the setXXX() call. This limitation is necessary to avoid the chance of data corruption when conversion of character data occurs and increases the length of the data. This limitation is enforced in the following situations:
(1)Using the JDBC thin driver
(2)Using binds (not defines)
(3)Using SQL CHAR datatypes
(4)Connecting to a database whose character set is neither ASCII (US7ASCII) nor ISO Latin1 (WE8ISO8859P1)
When the database character set is neither US7ASCII nor WE8ISO8859P1, the JDBC thin driver converts Java UTF-16 characters to UTF-8 encoding bytes for SQL CHAR binds. The UTF-8 encoding bytes are then transferred to the database, and the database converts the UTF-8 encoding bytes to the database character set encoding.”
原来是JDBC在转换过程中对字符串的长度做了限制。这个限制和数据库中字段的实际长度没有关系。
所以,setCharacterStream()方法可以逃过字符转换限制,也就成为了解决此问题的方案之一。
而JDBC对转换字符长度的限制是为了转换过程中的数据扩展。
根据实际测试结果,在ZHS16GBK字符集和thin驱动下,2000-4000长度的varchar字段都只能插入1333个字节(约666个汉字)。
备注:换最新的Oracle10g驱动,可能会播入更多,驱动问题。
发表评论
-
Srping配置阿里数据库连接池(Druid)
2015-10-19 13:49 2087Srping配置阿里数据库连接池(Druid) POM. ... -
Oracle 常用函数
2015-08-27 16:08 1085Oracle 常用函数 获取前10个小时的时间: sel ... -
Linux安装MYSQL(手工编译)
2015-08-02 14:22 3681Linux安装MYSQL(手工编译) 创建目录 ... -
Oracle 存储过程中打印SQL影响的行数
2015-07-07 11:41 1758Oracle 存储过程中打印SQL影响的行数 db ... -
更新多个字段的UPDATE语句
2015-06-19 16:18 4033更新多个字段的UPDATE语句 ... -
解决HSQL中java.lang.NoClassDefFoundError:java/sql/Savepoint错误
2011-07-16 09:35 1580解决HSQL中 java.lang.NoClassDefFo ... -
rank() function in application
2011-05-27 13:16 1408rank() function in application ... -
Oracle Statements
2011-05-23 09:33 637Oracle Statements --crea ... -
Each score of subjects is bigger than a number
2011-05-08 18:31 1295Each score of subjects is bigge ... -
DB2 Statements
2011-04-14 16:58 1172DB2 Statements 生成1-8之间的随机整数 ... -
数据表纵转横
2010-01-26 15:18 1918数据表纵转横 方法一: --创建函数与类型 cre ... -
Oracle优化器Optimizer详解(转)
2010-01-13 11:24 2427Oracle优化器Optimizer详解(转) ... -
oracle 实现 split 函数
2010-01-05 10:46 3060oracle 实现 split 函数 CREATE O ... -
row_number()over函数的使用(转)
2009-12-16 16:05 1948row_number()over函数的使用(转) ... -
Oracle随机函数
2009-11-25 18:05 3935Oracle随机函数 --创建55到100之间随机数( ... -
Oracle取整的函数
2009-11-25 18:05 2922Oracle取整的函数 1.取整(大) sel ... -
Oracle rownum使用经验总结
2009-11-25 17:38 1621Oracle rownum使用经验总 ... -
Oracle TIMESTAMP 的使用
2009-11-13 17:15 4215Oracle TIMESTAMP 的使用 TIMEST ... -
使用预编译语句设置null值(preparedStatement.setObject)
2009-10-22 16:40 3287使用预编译语句设置null值(preparedStatemen ... -
ORACLE 常用命令
2009-10-20 15:52 1399ORACLE 常用命令 1.用命令行执行一个.sq ...
相关推荐
此实例意在解决预处理命令PreparedStatement的setString()方法,在sql2008数据库中写入数据时,会自动补足空格的问题, 同时此实例也解决了当存在自动补足空格的问题时,使用nvarchar可以使查找出来的数据与原输入...
preparedStatement.setString (1, username); ResultSet resultSet = preparedStatement.executeQuery (); if(!resultSet.next()) occupied=false; preparedStatement.close (); ConnDB.terminate(); } ...
我们知道进行编码和转码工作都是集中在JDBC的两个接口PreparedStatement和ResultSet上进行的,主要涉及PreparedStatement的setString方法以及ResultSet的getString方法。前面我们讲过需要加入一个连接封装层来对...
关于PreparedStatement插入Date类型值的方法.txt
在java中向访问数据库的sql语句一般放到类PreparedStatement类构造函数中,这里遇到的问题就是向sql语句中用setDate()插入时间时不能用java.util.date,而应用java.sql.date,这里就讲述了解决方法,一种是插入...
jdbc2.0版 PreparedStatement接口的用法
//SQL 语句被预编译并存储在 PreparedStatement 对象中。然后可以使用此对象多次高效地执行该语句。 private ResultSet resultSet;//结果集 public boolean addSupplier(SupplierData s)//添加供应商 { ...
java中PreparedStatement和Statement的区别
NULL 博文链接:https://huiminchen.iteye.com/blog/1097332
PreparedStatement详细用法
练习3:使用PreparedStatement插入宠物信息.zip
JDBC中PreparedStatement接口提供的execute、executeQuery和executeUpdate之间的区别及用法
JDBC基础教程之PreparedStatement.doc )
Statement和PreparedStatement之间的区别
NULL 博文链接:https://chaoyi.iteye.com/blog/2088080
MySql练习3:使用PreparedStatement插入宠物信息.zip MySql练习3:使用PreparedStatement插入宠物信息.zip MySql练习3:使用PreparedStatement插入宠物信息.zip
jdbc中preparedStatement比Statement的好处
主要介绍了Java使用PreparedStatement接口及ResultSet结果集的方法,结合实例形式分析了PreparedStatement接口及ResultSet结果集的相关使用方法与操作注意事项,需要的朋友可以参考下
NULL 博文链接:https://stevenjohn.iteye.com/blog/968877