`

java.sql.SQLException: ORA-01461: can bfor insert into a LONG column问题分析与小结

阅读更多

java.sql.SQLException: ORA-01461: can bfor insert into a LONG column

 

1.发现系统报此问题的第一反应是插入数据时,数据长度超出数据库的字段长度。

2.而根据错误日志不难分析出是向邮件发送信息表中插入数据时,数据超过定义的最大值限制了,但到底是哪个字段,需进一步看一下代码和日志。

3.根据错误日志的时间找到跟踪日志,找到组装邮件DTO的数据,一个一个排查,最终发现只可能是邮件内容超出长度了。

但邮件内容是有长度判断与处理的(即:判断是否超过数据库字段所设置的4000长度,如果超过了,进行截取处理)

String emailContent = null;
if(mailContent != null){
	emailContent= mailContent.buildMailContent(args);
}
if(emailContent!=null&&emailContent.length()>4000){
	emailContent=emailContent.substring(0, 4000);
}
mailDTO.setEmailContent(emailContent);

         进一步分析,发现邮件内容的组装有html标签及样式的定义;而查看跟踪日志,发现’<’被替换为’&lt;’、’>’被替换为’&gt;’,于是我就主观的认为是在保存至数据库时,'<'、'>'标签被转义处理(即’<’变成了’&lt;’,仅此一个’<’的长度由1变成了4)。

        后来,将跟踪日志中的邮件内容拷出,将其全部’&lt;’替换为’<’、’&gt;’替换为’>’,并将内容中的单引号再加一个单引号的转义处理,通过PL/SQL更新开发环境里的一条记录,报超出长度错误提示。经一步步减少字符长度,最终发现:“将内容去掉6个汉字或11个英文字母,都能正常更新成功”。按上面的在保存至数据库时,'<'、'>'标签被转义处理的原因推测,减少6个汉字或11个英文字母,应该还是会超出长度。

        于是,我将邮件内容中的所有’&lt;’替换为’<’、’&gt;’替换为’>’ ,在UltraEdit-32中发现其长度是4011(正好符合上面更新SQL  减少11个英文字母能正常更新),此时,想到原来代码扫描时的getByte()方法,有字符编码格式的问题。

     进一步,我将’&lt;’替换为’<’、’&gt;’替换为’>’的邮件内容字符串进行了如下测试:

//全部’&lt;’替换为’<’,全部’&gt;’替换为’>’
String res3 = "<html><style>th , td{font-size: 13px;color: #4f5b75;font-weight: bold;border: 1px solid #95a7bf;border-collapse: collapse;padding: 4px;height: 22px;}</style><body>尊敬的XXX:<br />  您好!<br />  ... 此处内容省略 ... </body></html>";
System.out.println("res3:" + res3.length());  //结果是:3801
		
byte[] b_str = res3.getBytes();
System.out.println("b_str:" + b_str.length);  //结果是:4011

        分析到这里,我们应该知道原因了。

    原因是:

    str.length()返回此字符串的长度。长度等于字符串中 Unicode 代码单元的数量。即不论是中文还是英文,都是按照1个长度来看待的,而不是根据所占的字节数来计算length长度。

    而我们的ORACLE数据库存储格式应该是UTF-8或GBK之类(肯定不是JAVA中的Unicode 代码单元的数量)。

//全部’&lt;’替换为’<’,全部’&gt;’替换为’>’
String res3 = "<html><style>th , td{font-size: 13px;color: #4f5b75;font-weight: bold;border: 1px solid #95a7bf;border-collapse: collapse;padding: 4px;height: 22px;}</style><body>尊敬的XXX:<br />  您好!<br />  ... 此处内容省略 ... </body></html>";
System.out.println("res3:" + res3.length());
		
byte[] b_str = res3.getBytes();
System.out.println("b_str:" + b_str.length);

try {
	byte[] b_str3 = res3.getBytes("GBK");
	System.out.println("GBK b_str3:" + b_str3.length);  //结果:4011
			
	byte[] b_str2 = res3.getBytes("UTF-8");
	System.out.println("UTF-8 b_str2:" + b_str2.length);  //结果:4221
} catch (UnsupportedEncodingException e1) {
	// TODO Auto-generated catch block
	e1.printStackTrace();
}

        发现用GBK编码解析这串字符串长度正好是4011。据此反推:我们的数据库的编码格式是GBK。

    简单来说,系统在组装邮件对象后对邮件内容长度进行判断(长度是3801)是满足小于4000的条件的,而到后台保存至数据库时,由于数据库是GBK编码的,按GBK编码,其长度为4011,超出数据库字段的定义长度4000。所以报“ORA-01461: can bfor insert into a LONG column”错误。

    解决方法:

    将原来的如下校验

if(mailContent != null){
	emailContent= mailContent.buildMailContent(args);
}

     改为:

if(emailContent != null) {
	byte[] bytes = emailContent.getBytes("GBK");
	if(bytes.length > 4000) {
		int tempLen = new String(bytes, 0, 4000, "GBK").length();
		//根据tempLen长度截取原字符串
		emailContent = emailContent.substring(0, tempLen);
	}
}

 

分享到:
评论

相关推荐

    解决Exception java.sql.SQLException ORA-00600 内部错误代码

    在oracle里面运行一下,解决Exception java.sql.SQLException ORA-00600 内部错误代码

    oracle+ora-各种常见java.sq

    在Oracle数据库操作中,我们经常会遇到与`java.sql.SQLException`相关的异常。这个异常通常是Java应用程序在尝试与Oracle数据库进行交互时出现的问题。本篇将详细探讨`java.sql.SQLException`的各种常见类型及其解决...

    java.sql.SQLException: 不支持的字符集 (在类路径中添加 orai18n.jar): ZHS16GBK

    java.sql.SQLException: 不支持的字符集 (在类路径中添加 orai18n.jar): ZHS16GBK ……

    ORA-00060: 等待资源时检测到死锁--oracle 数据库表死锁异常

    在Oracle数据库系统中,"ORA-00060: 等待资源时检测到死锁" 是一个常见的错误提示,它表明两个或多个事务在执行过程中陷入了无法继续进行的状态,因为彼此都在等待对方释放资源。这种情况通常发生在并发操作中,比如...

    java.sql.SQLException: 结果集已耗尽

    在Java编程中,`java.sql.SQLException: 结果集已耗尽` 是一个常见的错误提示,通常出现在处理数据库查询结果集时。这个异常表明程序试图访问已经没有数据的结果集中下一行,即所有行已经被遍历完,尝试访问超出范围...

    Caused by: java.sql.SQLException: JZ0SJ: 没有在此数据库中发现元数据存取器信息。 请按 jConnect 文档中所述安装

    标题中的“Caused by: java.sql.SQLException: JZ0SJ: 没有在此数据库中发现元数据存取器信息。 请按 jConnect 文档中所述安装”是一个典型的错误信息,表明在尝试使用Java数据库连接(JDBC)驱动程序访问数据库时...

    服务器出现java.sql.SQLException No suitable driver found for 的.pdf

    ### 服务器出现java.sql.SQLException No suitable driver found for 的解析与解决方案 #### 问题背景 在进行Servlet开发过程中,尤其是在尝试连接数据库时,遇到了一个常见的异常:“java.sql.SQLException: No ...

    JDBC驱动for sqlserver、oracle、mysql

    Microsoft提供了适用于Java的JDBC驱动,名为"Microsoft JDBC Driver for SQL Server",它支持Type 4,允许Java应用程序直接与SQL Server进行通信。安装后,通过`Class.forName()`加载驱动,并使用`DriverManager....

    oracle ora-各种常见java.sql.SQLException归纳

    Oracle ORA 异常处理详解 Oracle 是一个强大的关系数据库管理系统,然而,在使用 Oracle 时,总是会遇到各种错误信息,这些错误信息是Oracle抛出的异常信息,用于提示开发者出现了什么问题。了解这些错误信息是...

    ora-dba.rar

    4. **数据库开发与管理**:ora-dba工具集还包含了数据库对象的创建、修改和删除功能,以及SQL查询和PL/SQL代码的编写与调试工具。这些功能使得数据库开发人员可以在同一平台上完成大部分工作。 5. **性能优化**:...

    ORA-28001 the password has expired密码过期.docx

    在Oracle数据库管理中,"ORA-28001 the password has expired" 是一个常见的错误,它表明数据库用户的密码已经超过了预设的有效期限,导致用户无法正常登录。这个错误主要出现在Oracle 11G及更高版本中,因为这些...

    ORA-01157解决方案.txt

    ### ORA-01157 错误详解与解决方案 #### 错误代码与含义 ORA-01157 错误是 Oracle 数据库中一个常见的错误代码,其全称是:“ORA-01157: 无法识别/文件 - DBWR 文件”。这个错误通常发生在数据库启动过程中,当...

    java.sql.SQLException: 内部错误: Unable to construct a Datum from the specified input

    Q: I am working with ... I am using updateBinaryStream method of resultset to update the BLOB field but it is failing after giving following exception java.sql.SQLException: Internal Error: Unable to

    oracle数据库的clob大字段在jdbc中的处理方式

    在Java中,当我们需要通过JDBC(Java Database Connectivity)接口与Oracle数据库交互时,处理CLOB字段可能会遇到一些挑战。这篇文档将详细阐述如何在JDBC中有效地读取和操作Oracle数据库的CLOB字段,并将其转换为...

    oracle jdbc dirver

    Oracle JDBC Driver是Oracle公司提供的用于Java应用程序与Oracle数据库交互的接口。它实现了Java Database Connectivity (JDBC) API,使得开发者可以使用Java语言来操作Oracle数据库,执行SQL语句,进行数据查询、...

    hive-jdbc-1.1.0-cdh5.4.5-standalone.jar

    Caused by: java.sql.SQLException: java.lang.ClassNotFoundException: org.apache.hive.jdbc.HiveDriver at com.trs.gateway.commons.hive.HiveFeature.getConnection(HiveFeature.java:57) at ...

    ora常用sql.rar

    "ora常用sql.rar"这个压缩包显然包含了DBA(Database Administrator,数据库管理员)在日常工作中经常会用到的一些Oracle SQL命令。让我们详细探讨一下这些关键命令及其用途。 1. **查看系统SGA区状态**: SGA...

    oracle实例的内存(SGA和PGA)进行调整,优化数据库性

    ### Oracle实例内存优化详解:SGA与PGA的调整策略 #### 概述 在Oracle数据库管理系统中,优化数据库性能往往涉及到对其内部结构的理解与微调,尤其是针对内存资源的合理分配。本文将深入探讨Oracle实例的内存管理...

    数据库连接利用工具–Sylas

    然而,描述中指出在使用过程中遇到了一些问题,这可能包括错误代码“ORA-24345:出现截断或空读取错误”,这是Oracle数据库系统中一个常见的错误,通常与数据读取或写入过程中的数据长度不匹配有关。 错误的产生...

    java.sql.SQLException: null,  message from server: “Host ‘%’ is not allowed to connect to

    java.sql.SQLException: null, message from server: “Host ‘223.72.41.7’ is not allowed to connect to this MySQL server” 客户端访问时报错: 解决方法: 1,登陆服务器 mysql&gt; use mysql; //用mysql ...

Global site tag (gtag.js) - Google Analytics