Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/366.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java SimpleJDBCall调用Pl/SQL过程——ORA-22922不存在LOB值_Java_Oracle_Jdbctemplate_Clob - Fatal编程技术网

Java SimpleJDBCall调用Pl/SQL过程——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

我得到了这个SQLException——ORA-22922不存在的LOB值

我的设想是:

  • 我正在调用一个接受结构数组的过程
  • 该结构包含三种类型,两种是date,一种是Clob
  • 当我使用Spring的SimpleJDBCall设置null而不是clob来执行该过程时,将执行语句并将数据写入数据库
  • 这表明我的SimpleJDBCall设置正确
  • 下面是我创建clob、数组和结构以及执行simpleJdbCall的代码

      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;
    }