Java SimpleJDBCall调用Pl/SQL过程——ORA-22922不存在LOB值
我得到了这个SQLException——ORA-22922不存在的LOB值 我的设想是:Java SimpleJDBCall调用Pl/SQL过程——ORA-22922不存在LOB值,java,oracle,jdbctemplate,clob,Java,Oracle,Jdbctemplate,Clob,我得到了这个SQLException——ORA-22922不存在的LOB值 我的设想是: 我正在调用一个接受结构数组的过程 该结构包含三种类型,两种是date,一种是Clob 当我使用Spring的SimpleJDBCall设置null而不是clob来执行该过程时,将执行语句并将数据写入数据库 这表明我的SimpleJDBCall设置正确 下面是我创建clob、数组和结构以及执行simpleJdbCall的代码 public void insertRecords(List<MyObje
public void insertRecords(List<MyObject> objectList) throws Exception {
Array array = null;
Connection connection = jdbcTemplate.getDataSource().getConnection();
OracleConnection oracleConnection = connection.unwarp(OracleConnection.class);
Object[] arrObj = new Object[objectList.size()];
Object[][] structObj = new Object[objectList.size()][3];
Clob clob = connection.createClob();
for(int loop = 0; loop < objectList.size(); loop++) {
clob.setString(objectList.get(loop).getData);
structObj[loop][0] = objectList.getDate1();
structObj[loop][1] = objectList.getDate2();
structObj[loop][2] = clob; //null;
arrObj[loop] = oracleConnection.createStruct(structName, structObj[loop]);
}
array = oracleConnection.createOracleArray(collectionName, arrObj);
Map<String, Array> inparam = new HashMap<~>;
inparam.put(arrayParamString, array);
//procInsertData is a SimpleJdbcCall
procInsertData.exexute(inparam);
clob.free();
}
我在这里面临同样的问题,但只有在尝试使用StoredProcedure执行此操作时才会遇到 但是这样
conn = datsource.getConnection();
cstmt = conn.prepareCall("{? = call schema.package.function(?)}");
cstmt.registerOutParameter(1, Types.CLOB);
cstmt.setClob(2, clob);
cstmt.execute();
工作正常。Clob实例绑定到用于创建它的“oracleConnection”,SimpleJDBCall使用另一个连接进行DB调用。从DB的角度来看,有两个独立的会话,这就是为什么SimpleJDBCall使用的会话中不存在clob的原因 SimpleJDBCall使用的连接必须用于Clob创建 通过实现SQLData和提取当前连接,我成功地解决了类似的问题:
Map<String, Object> values = new HashMap<>();
values.put("IN_bean_type", new MyBean());
simpleJdbcCallOperations.execute(values);
我也有类似的问题。你可以纠正它。我做出我的贡献,希望它能为你服务
public PreparedStatement insertaReprocesos(TimerLog timer, List<ReprocesosDTO> listaInsertaProcesos) throws SQLException, Exception{
Connection conexion = null;
CallableStatement cstmt = null;
String query = null;
try {
conexion = JDBCUtils.getConnection(UtilProperties.DATASOURCE);
Connection conexion2 = JDBCUtils.getImplementsConnectionAllServer(conexion);
query= UtilProperties.SP_INSERTA_REPROCESOS;
cstmt = conexion.prepareCall(query);
Object[] recordArray = new Object[6];
Struct[] structs = new Struct[listaInsertaProcesos.size()];
int registroCont = 0;
Clob myClob = conexion2.createClob();
for(ReprocesosDTO registro : listaInsertaProcesos) {
Reader reader = registro.getFcregistro().getCharacterStream();//esta variable la esta declarada como Clob
BufferedReader br = new BufferedReader(reader);
myClob.setString(1, br.readLine());
recordArray[0] = registro.getFiprocesoId();
recordArray[1] = registro.getFdfecha();
recordArray[2] = (registro.getFisecuencia());
recordArray[3] = registro.getFistatusid();
recordArray[4] = myClob;// este dato en BD esta declarado como CLOB
recordArray[5] = registro.getFcusuario();
structs[registroCont++] = conexion2.createStruct(UtilProperties.TYP_REPORTE_PROCESOS, recordArray);
}
Array oracleRecord = ((OracleConnection) conexion2).createOracleArray(UtilProperties.TYPE_TAREPORTE,structs);
cstmt.setArray(1, oracleRecord);
cstmt.registerOutParameter(MonitorConstants.PA_CODIGO_SALIDA_2,OracleTypes.VARCHAR);
cstmt.registerOutParameter(MonitorConstants.PA_MENSAJE_SALIDA_3,OracleTypes.VARCHAR);
cstmt.execute();
} catch (SQLException e) {
LOGGER.error("Mensaje "+e.getMessage()+"Causa: "+e.getCause());
timer.setTiempoParcial(MonitorConstants.MONITOR_DAO, MonitorConstants.INSERTA_PROCESOS);
throw new SQLException(e);
} catch (Exception e) {
timer.setTiempoParcial(MonitorConstants.MONITOR_DAO, MonitorConstants.INSERTA_PROCESOS);
throw new Exception(e);
}
return cstmt;
}
public PreparedStatement insertapreprocesos(TimerLog timer,List listaInsertaProcesos)抛出SQLException,Exception{
连接conexion=null;
CallableStatement cstmt=null;
字符串查询=null;
试一试{
conexion=JDBCUtils.getConnection(UtilProperties.DATASOURCE);
连接conexion2=JDBCUtils.getImplementsConnectionAllServer(conexion);
query=UtilProperties.SP_INSERTA_REPROCESOS;
cstmt=conexion.prepareCall(查询);
Object[]recordArray=新对象[6];
Struct[]structs=new Struct[listaInsertaProcesos.size()];
int registroCont=0;
Clob myClob=conexion2.createClob();
用于(向注册处报告:Listainsertaproceos){
Reader Reader=registro.getFcregistro().getCharacterStream();//esta变量la esta declarada como Clob
BufferedReader br=新的BufferedReader(读卡器);
myClob.setString(1,br.readLine());
recordArray[0]=registro.getFiprocesoId();
recordArray[1]=registro.getFdfecha();
recordArray[2]=(registro.getFisecuencia());
recordArray[3]=registro.getFistatusid();
recordArray[4]=myClob;//este dato en BD esta DECLASSARDO como CLOB
recordArray[5]=registro.getFcusuario();
structs[registroCont++]=conexion2.createStruct(UtilProperties.TYP_REPORTE_PROCESOS,recordArray);
}
数组oracleRecord=((OracleConnection)conexion2.createOracleArray(utilproperty.TYPE_TAREPORTE,structs);
cstmt.setArray(1,oracleRecord);
cstmt.registerOutParameter(MonitorConstants.PA_CODIGO_SALIDA_2,OracleTypes.VARCHAR);
cstmt.registerOutParameter(MonitorConstants.PA_MENSAJE_SALIDA_3,OracleTypes.VARCHAR);
cstmt.execute();
}捕获(SQLE异常){
LOGGER.error(“Mensaje”+e.getMessage()+“Causa:”+e.getCause());
timer.settiemoparcial(MonitorConstants.MONITOR\u DAO,MonitorConstants.INSERTA\u PROCESOS);
抛出新的SQLException(e);
}捕获(例外e){
timer.settiemoparcial(MonitorConstants.MONITOR\u DAO,MonitorConstants.INSERTA\u PROCESOS);
抛出新异常(e);
}
返回cstmt;
}
我不这么认为。是3的有效结论。如果Spring忽略了您设置为null的LOB insert参数,该怎么办<代码>插入t(a,b)值…与插入t(a,b,lob)值…有很大不同。您是否启用了调试日志记录以查看数据库中哪些SQL语句出现问题?感谢@MarcelStör的输入,我已尝试在Oracle上测试该过程以插入数据,该过程正常工作。此外,在上面的代码中,当struct被创建时,数据库中的struct对象在创建之前会检查这些输入类型。不确定如何在Spring/Java端启用调试日志。有什么提示吗?@MarcelStör添加了调试日志请用英语提问。
class MyBean implements SQLData {
...
@Override
public void writeSQL(SQLOutput stream) throws SQLException {
...
Clob clob = ((OracleSQLOutput)stream).getSTRUCT().getJavaSqlConnection().createClob(); //hack to get the current connection
clob.setString(1, "stringValue");
stream.writeClob(clob);
...
}
...
}
public PreparedStatement insertaReprocesos(TimerLog timer, List<ReprocesosDTO> listaInsertaProcesos) throws SQLException, Exception{
Connection conexion = null;
CallableStatement cstmt = null;
String query = null;
try {
conexion = JDBCUtils.getConnection(UtilProperties.DATASOURCE);
Connection conexion2 = JDBCUtils.getImplementsConnectionAllServer(conexion);
query= UtilProperties.SP_INSERTA_REPROCESOS;
cstmt = conexion.prepareCall(query);
Object[] recordArray = new Object[6];
Struct[] structs = new Struct[listaInsertaProcesos.size()];
int registroCont = 0;
Clob myClob = conexion2.createClob();
for(ReprocesosDTO registro : listaInsertaProcesos) {
Reader reader = registro.getFcregistro().getCharacterStream();//esta variable la esta declarada como Clob
BufferedReader br = new BufferedReader(reader);
myClob.setString(1, br.readLine());
recordArray[0] = registro.getFiprocesoId();
recordArray[1] = registro.getFdfecha();
recordArray[2] = (registro.getFisecuencia());
recordArray[3] = registro.getFistatusid();
recordArray[4] = myClob;// este dato en BD esta declarado como CLOB
recordArray[5] = registro.getFcusuario();
structs[registroCont++] = conexion2.createStruct(UtilProperties.TYP_REPORTE_PROCESOS, recordArray);
}
Array oracleRecord = ((OracleConnection) conexion2).createOracleArray(UtilProperties.TYPE_TAREPORTE,structs);
cstmt.setArray(1, oracleRecord);
cstmt.registerOutParameter(MonitorConstants.PA_CODIGO_SALIDA_2,OracleTypes.VARCHAR);
cstmt.registerOutParameter(MonitorConstants.PA_MENSAJE_SALIDA_3,OracleTypes.VARCHAR);
cstmt.execute();
} catch (SQLException e) {
LOGGER.error("Mensaje "+e.getMessage()+"Causa: "+e.getCause());
timer.setTiempoParcial(MonitorConstants.MONITOR_DAO, MonitorConstants.INSERTA_PROCESOS);
throw new SQLException(e);
} catch (Exception e) {
timer.setTiempoParcial(MonitorConstants.MONITOR_DAO, MonitorConstants.INSERTA_PROCESOS);
throw new Exception(e);
}
return cstmt;
}