2017-03-09 161 views
0

我将java String类型映射到ibatis sql配置文件中的CLOB类型,并在我使用此配置插入记录时遇到ORA错误。当字符串的长度为4000个字符或更少时,这似乎工作文件。为了测试出长字符串,我创建了一个字段中包含5000个字符的随机字符串(DATA_CODESCHEMA_CODE)。从java中插入到CLOB类型时的ORA-01461字符串

我的SQL文件看起来像:

<parameterMap class="map" id="map"> 
<parameter property="QUERY_HASH" javaType="java.math.BigDecimal" jdbcType="NUMBER" /> 
<parameter property="LOCATION" javaType="java.lang.String" jdbcType="VARCHAR2" /> 
<parameter property="HOST_NAME" javaType="java.lang.String" jdbcType="VARCHAR2" /> 
<parameter property="SERVER_PORT" javaType="java.lang.String" jdbcType="VARCHAR2" /> 
<parameter property="DATA_CODE" javaType="java.lang.String" jdbcType="CLOB" /> 
<parameter property="SCHEMA_CODE" javaType="java.lang.String" jdbcType="CLOB" /> 
<parameter property="CREATED" javaType="java.util.Date" jdbcType="DATE" /> 
</parameterMap> 
<insert id="INSERT__QUERY_CACHE" parameterClass="map"> 
    <![CDATA[ 
    INSERT INTO "QUERY_CACHE" (query_hash, location, host_name, server_port, data_code, schema_code, created) 
    SELECT #QUERY_HASH#, #LOCATION#, #HOST_NAME#, #SERVER_PORT#, #DATA_CODE#, #SCHEMA_CODE#, #CREATED# FROM DUAL WHERE NOT EXISTS (SELECT * FROM 
    SAVRO_CONN_QUERY_CACHE WHERE query_hash = #QUERY_HASH# and location=#LOCATION# and host_name = #HOST_NAME# and server_port = #SERVER_PORT#) 
    ]]> 
</insert> 

和我的Java代码:

Map<String, Object> iterMap = new HashMap<String, Object>(); 
iterMap.put("QUERY_HASH", key); 
iterMap.put("LOCATION", cacheEntry.className); 
iterMap.put("HOST_NAME", hostName); 
iterMap.put("SERVER_PORT", serverPort); 
////// junk string - START 
StringBuilder builder = new StringBuilder(); 
builder.append("5000 chars string"); 
builder.append(RandomStringUtils.random(5000)); 
iterMap.put("DATA_CODE", builder.toString()); 
iterMap.put("SCHEMA_CODE", builder.toString()); 
//// junk string - END 
iterMap.put("CREATED", new Date(System.currentTimeMillis())); 
insert(QRY__INSERT, iterMap); 

异常跟踪是:

 org.springframework.jdbc.UncategorizedSQLException: SqlMapClient operation; uncategorized SQLException for SQL []; SQL state [72000]; error code [1461]; 
    --- The error occurred in com/mycomp/sql_config.xml. 
    --- The error occurred while applying a parameter map. 
    --- Check the INSERT__QUERY_CACHE-InlineParameterMap. 
    --- Check the statement (update failed). 
    --- Cause: java.sql.SQLException: ORA-01461: can bind a LONG value only for insert into a LONG column 
    ; nested exception is com.ibatis.common.jdbc.exception.NestedSQLException: 
    --- The error occurred in com/mycomp/sql_config.xml. 
    --- The error occurred while applying a parameter map. 
    --- Check the INSERT__QUERY_CACHE-InlineParameterMap. 
    --- Check the statement (update failed). 
    --- Cause: java.sql.SQLException: ORA-01461: can bind a LONG value only for insert into a LONG column 

    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:83) 
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80) 
    at org.springframework.orm.ibatis.SqlMapClientTemplate.execute(SqlMapClientTemplate.java:206) 
    at org.springframework.orm.ibatis.SqlMapClientTemplate.insert(SqlMapClientTemplate.java:367) 
    at com.mycomp.mypackage.MyCache.saveCache(MyCache.java:142) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:483) 
    at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:64) 
    at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:53) 
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) 
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
    at java.lang.Thread.run(Thread.java:745) 
    Caused by: com.ibatis.common.jdbc.exception.NestedSQLException: 
    --- The error occurred in com/mycomp/sql_config.xml. 
    --- The error occurred while applying a parameter map. 
    --- Check the INSERT__QUERY_CACHE-InlineParameterMap. 
    --- Check the statement (update failed). 
    --- Cause: java.sql.SQLException: ORA-01461: can bind a LONG value only for insert into a LONG column 

    at com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.executeUpdate(MappedStatement.java:107) 
    at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.insert(SqlMapExecutorDelegate.java:393) 
    at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.insert(SqlMapSessionImpl.java:82) 
    at org.springframework.orm.ibatis.SqlMapClientTemplate$8.doInSqlMapClient(SqlMapClientTemplate.java:369) 
    at org.springframework.orm.ibatis.SqlMapClientTemplate.execute(SqlMapClientTemplate.java:203) 
    ... 15 more 
    Caused by: java.sql.SQLException: ORA-01461: can bind a LONG value only for insert into a LONG column 

    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:445) 
    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:396) 
    at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:879) 
    at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:450) 
    at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:192) 
    at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:531) 
    at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:207) 
    at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:1044) 
    at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1329) 
    at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3584) 
    at oracle.jdbc.driver.OraclePreparedStatement.execute(OraclePreparedStatement.java:3685) 
    at oracle.jdbc.driver.OraclePreparedStatementWrapper.execute(OraclePreparedStatementWrapper.java:1376) 
    at org.apache.commons.dbcp.DelegatingPreparedStatement.execute(DelegatingPreparedStatement.java:172) 
    at org.apache.commons.dbcp.DelegatingPreparedStatement.execute(DelegatingPreparedStatement.java:172) 
    at com.ibatis.sqlmap.engine.execution.SqlExecutor.executeUpdate(SqlExecutor.java:80) 
    at com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.sqlExecuteUpdate(MappedStatement.java:216) 
    at com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.executeUpdate(MappedStatement.java:94) 
    ... 19 more 

我们使用iBATIS 2.3.4春季3.3 我在其他文章搜索类似的问题,但我找不到他们的线索。任何线索请..

回答

0

显然有没有简单的方法来从Java插入大的值在Oracle中,因为JDBC驱动程序没有原生支持Reader和InputStream。这是在SO的另一个主题: Java: How to insert CLOB into oracle database

+0

我使用iBATIS。我想出了一个方法来与ibatis一起做。参考我的答案。 – sandeep

0

我在做insert into .. select if not exists。我的要求是仅当数据不存在于表中时才插入数据。它的工作

  • 拆分此之后分成两个单独的查询 - 一个用于选择,一个是 插入。
  • 因为,我反正发送一个map参数,我删除了paramMap xml。
  • 附加CLOB查询在XML

    <insert id="INSERT__QUERY_CACHE" 
    parameterClass="Map"> 
    <![CDATA[ 
    INSERT INTO "QUERY_CACHE" (query_hash, location, host_name, server_port, data_code, schema_code, created) 
    values (#QUERY_HASH#, #LOCATION#, #HOST_NAME#, #SERVER_PORT#, #DATA_CODE:CLOB#, #SCHEMA_CODE:CLOB#, sysdate) 
    ]]> 
    </insert> 
    
    <select id="SELECT__FROM_CACHE" resultClass="int"> 
    <![CDATA[ 
    SELECT count(0) as CNT FROM QUERY_CACHE WHERE query_hash = #QUERY_HASH# and location=#LOCATION# and host_name = #HOST_NAME# and server_port = #SERVER_PORT# 
    ]]> 
    </select> 
    

在Java中指定参数时,

Map<String, Object> selectMap = new HashMap<String, Object>(); 
selectMap.put("QUERY_HASH", key); 
selectMap.put("LOCATION", cacheEntry.className); 
selectMap.put("HOST_NAME", hostName); 
selectMap.put("SERVER_PORT", serverPort); 

Integer count = (Integer) queryForObject(QRY__SELECT_FROM_CACHE, selectMap); 
if(count == 0) { 
    Map<String, Object> iterMap = new HashMap<String, Object>(); 
    iterMap.put("QUERY_HASH", key); 
    iterMap.put("LOCATION", cacheEntry.className); 
    iterMap.put("HOST_NAME", hostName); 
    iterMap.put("SERVER_PORT", serverPort); 
    iterMap.put("DATA_CODE", cacheEntry.dataCode); 
    iterMap.put("SCHEMA_CODE", cacheEntry.schemaCode); 
    insert(QRY__INSERT, iterMap); 
}