工作中,保存数据的时候出现该问题,说字符串问题过长。过长的字段是一个用来保存xml格式的字符串,字段类型已经设置成CLOB,但是还是出现字符串过长问题。
在SQLServer应该不会出现该问题,该问题中字符串文字太长,并不是字段的字符串过长,而是整个SQL语句过长。Oracle中一个sql语句最长支持4000个字符的长度,而sql是调
用公司框架生成的,生成的时候应该是采用拼接的方法,字段中字符过长,拼接出来的sql语句也就太长,超过了4000个,在Oracle中会报这个错误。
google,度娘的时候大家分享的 方法也有很多种:
1:绑定变量,写pl/sql
2:使用java操作CLOB对象
3:用OracleCommand去操作
这几种方法都不太熟练,也相对有些复杂,解决的时候又会出现一些新的问题。最后发现了一种简单的方法:
不采用公司框架生成sql,自己使用原始的jdbc的方法去插入数据:.
map.get("TEMPLATE_INFO")就是那个超长的字符串
pstmt.setCharacterStream(4, new StringReader(map.get("TEMPLATE_INFO")), map.get("TEMPLATE_INFO").length());
采用这样的方法来设置CLOB类型的字段,就不会出现ORA-07104:字符串文字太长的问题。
public String addAlarmConfigTemplate(String objXml) throws Exception
{
Connection conn = null;
PreparedStatement pstmt = null;
int newId;
try
{
HashMap<String, String> map = SerializerUtil.deserialize(objXml, "");
String getNewId = "SELECT MAX(TEMPLATE_ID) FROM BMP_ALARMCONFIGTEMPLATE";
String insertSql =
"INSERT INTO BMP_ALARMCONFIGTEMPLATE (TEMPLATE_ID,TEMPLATE_NAME,TEMPLATE_TYPE,TEMPLATE_INFO,CREATE_TIME) Values (?,?,?,?,?)";
ISqlExecutor exec = SqlExecutorFacotry.getSqlExecutor();
ConnectionInfo info = exec.getConnectionInfo();
conn = SqlHelper.getConnection(info);
//获取插入新记录的id
pstmt = conn.prepareStatement(getNewId);
ResultSet rs = pstmt.executeQuery();
if ((null != rs) && rs.next())
newId = rs.getInt("MAX(TEMPLATE_ID)") + 1;
else
newId = 1;
//插入记录
pstmt = conn.prepareStatement(insertSql);
pstmt.setInt(1, newId);
pstmt.setString(2, map.get("TEMPLATE_NAME"));
pstmt.setInt(3, Integer.parseInt(map.get("TEMPLATE_TYPE")));
pstmt.setCharacterStream(4, new StringReader(map.get("TEMPLATE_INFO")), map.get("TEMPLATE_INFO").length());
pstmt.setTimestamp(5, new Timestamp(new Date().getTime()));
pstmt.executeUpdate();
}
catch (Exception e)
{
logger.error("新增报警配置模板(BMP_ALARMCONFIGTEMPLATE)失败!");
throw e;
}
finally
{
if (null != pstmt)
pstmt.close();
if (null != conn)
conn.close();
}
return "" + newId;
}