工作中,保存数据的时候出现该问题,说字符串问题过长。过长的字段是一个用来保存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; }