为纪念中华人民共和国建军90周年,特此一篇,以此纪念,我军威武!!!
一、问题背景
项目中商品发布,却没有保存成功。
二、问题定位
初步判断向数据库中保存时出现了错误,查看日志文件,由于日志文件过大就采用grep进行搜索(再一次说明grep 的强大)
其中 “ReserveProductService.update” 是要搜索的关键字,catalina.out是日志文件, -n 显示搜索内容所在行数, -B 2 是显示搜索内容的前两行(还有-C 前后几行,-A 后几行)
将2换成更大值显示内容如下
问题原因就出来了,由于插入内容长度超过了字段长度限制
注:为了方便分析错误日志,将日志内容修改如下,修改后会打印到对应的日志文件中,而不是全部输入到tomcat控制台中
修改前
public static void dbLogError(StringBuffer errorMessage,Exception ex) { if (dbLog != null) { dbLog.error(errorMessage); } if (isPrintStackTrace && ex != null) { ex.printStackTrace(); } }
修改后
public static void dbLogError(StringBuffer errorMessage,Exception ex) { if (dbLog != null) { dbLog.error(errorMessage); } if (isPrintStackTrace && ex != null) { dbLog.error(ex.getMessage(),ex); //将错误栈打印到日志文件中 ex.printStackTrace(); } }
三、问题分析
查看该字段在数据库中的设置
qualitystan VARCHAR2(254) default '',其就是254
而前台限制的是200字
if(trim(document.getElementsByName('bean.qualityStan')[0].value).length > 200){ alert("您输入的质量标准超过了200字,请重新输入!"); document.getElementsByName('bean.qualityStan')[0].focus(); return; }
为什么错误栈中却提示的是实际值是314。看下Oracle中varchar2长度的说明
oracle 中的dataType可参考
http://docs.oracle.com/cd/E11882_01/server.112/e41084/sql_elements001.htm#SQLRF30020
查看项目中用的编码格式
SELECT parameter,VALUE FROM nls_database_parameters WHERE parameter IN ('NLS_CHARACTERSET','NLS_NCHAR_CHARACTERSET');
NLS_NCHAR_CHARACTERSET AL16UTF16
NLS_CHARACTERSET ZHS16GBK
说明:
NLS_CHARACTERSET是数据库字符集,NLS_NCHAR_CHARACTERSET是国家字符集(Oracle中字符集的介绍可参考http://www.cnblogs.com/KissKnife/archive/2011/11/11/2245410.html)
Oracle中有两大类字符型数据,VARCHAR2是按照数据库字符集来存储数据。而NVARCHAR2是按照国家字符集存储数据的。同样,CHAR和NCHAR也一样,一是数据库字符符,一是国家字符集。
Oracle中有两大类字符型数据,VARCHAR2是按照数据库字符集来存储数据。而NVARCHAR2是按照国家字符集存储数据的。同样,CHAR和NCHAR也一样,一是数据库字符符,一是国家字符集。
NVARCHAR2(N),其中的N是指字符数,不是字节数。不过其最大长度是以字节为单位,即4000字节。
VARCHAR2(N),其中的N可能是指字符数,也可能是指字节数。你可以显式地在声明的时候指定,比如VARCHAR2(10 BYTE)或者VARCHAR2(10 CHAR),未显式指明时,则由参数NLS_LENGTH_SEMANTICS决定。
SQL> SELECT parameter,VALUE FROM nls_database_parameters; PARAMETER VALUE ------------------------------ -------------------------------------------------------------------------------- NLS_NCHAR_CHARACTERSET AL16UTF16 NLS_LANGUAGE AMERICAN NLS_TERRITORY AMERICA NLS_CURRENCY $ NLS_ISO_CURRENCY AMERICA NLS_NUMERIC_CHARACTERS .,NLS_CHARACTERSET ZHS16GBK NLS_CALENDAR GREGORIAN NLS_DATE_FORMAT DD-MON-RR NLS_DATE_LANGUAGE AMERICAN NLS_SORT BINARY NLS_TIME_FORMAT HH.MI.SSXFF AM NLS_TIMESTAMP_FORMAT DD-MON-RR HH.MI.SSXFF AM NLS_TIME_TZ_FORMAT HH.MI.SSXFF AM TZR NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZR NLS_DUAL_CURRENCY $ NLS_COMP BINARY NLS_LENGTH_SEMANTICS BYTE NLS_NCHAR_CONV_EXCP FALSE NLS_RDBMS_VERSION 11.2.0.4.0
那么字段QUALITYSTAN(varchar2(254))的编码格式是ZHS16GBK,长度限制的是254个字节。汉字的话会占用2个字节,因此如果是200个汉字的话,其实是400个字节,而字段长度确实254个字节。因此这个时候还是超出了。
四、问题解决
1)可以修改数据库字段长度,或者类型(用varchar2(254char)或者nvarchar2(254))
2)修改前端限制,这个比较方便简单
if(trim(document.getElementsByName('bean.qualityStan')[0].value).length > 120){ alert("您输入的质量标准超过了120字,请重新输入!"); document.getElementsByName('bean.qualityStan')[0].focus(); return; }
总结:看似简单的问题,其实更需要扎实的基础。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。