为纪念中华人民共和国建军90周年,特此一篇,以此纪念,我军威武!!!
一、问题背景
项目中商品发布,却没有保存成功。
二、问题定位
其中 “ReserveProductService.update” 是要搜索的关键字,catalina.out是日志文件, -n 显示搜索内容所在行数, -B 2 是显示搜索内容的前两行(还有-C 前后几行,-A 后几行)
问题原因就出来了,由于插入内容长度超过了字段长度限制
修改前
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可参考
查看项目中用的编码格式
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个字节。因此这个时候还是超出了。
四、问题解决
2)修改前端限制,这个比较方便简单
if(trim(document.getElementsByName('bean.qualityStan')[0].value).length > 120){ alert("您输入的质量标准超过了120字,请重新输入!"); document.getElementsByName('bean.qualityStan')[0].focus(); return; }
总结:看似简单的问题,其实更需要扎实的基础。