为纪念中华人民共和国建军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也一样,一是数据库字符符,一是国家字符集。
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;
}
总结:看似简单的问题,其实更需要扎实的基础。 (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|