如何在存储过程中将Java String转换为Oracle Clob

时间:2017-07-20 06:22:31

标签: java oracle

我的程序如下

create or replace PROCEDURE  PROCESS_MESSAGE(
    MESSAGE_ENTITY IN T_MESSAGE_ENTITY,
    STATUS OUT VARCHAR2
.
.

其中T_MESSAGE_ENTITY是包含CLOB

字段的类型
create or replace TYPE T_MESSAGE_ENTITY FORCE AS OBJECT (
COLS CLOB,
VALS CLOB
.
.
)

我必须将T_MESSAGE_ENTITY作为输入参数传递给过程,并使用ARRAY尝试这些CLOB值。

objMsgEntityArray[0] = colString.getBytes();
objMsgEntityArray[1] = valString.getBytes();

并使用callableStmt.setObject()

传递此对象

它给我以下错误。

  

将数据合并到Issue时发生了SQLException   table.java.sql.SQLException:无法转换为内部   代表:[B @ 3cbbfe22 at   oracle.jdbc.oracore.OracleTypeCLOB.toDatum(OracleTypeCLOB.java:71)

3 个答案:

答案 0 :(得分:1)

如果您想在java中使用udt(用户定义类型),则必须使用java.sql.SQLData接口创建映射类或 利用STRUCT类。在我的例子中,我将使用第二个选项

您的类型和程序。

create or replace TYPE T_MESSAGE_ENTITY FORCE AS OBJECT (
  COLS CLOB,
  VALS CLOB    
);

create or replace PROCEDURE  PROCESS_MESSAGE(
    MESSAGE_ENTITY IN T_MESSAGE_ENTITY,
    STATUS OUT VARCHAR2) 
    is 
    begin         
     status := MESSAGE_ENTITY.cols||'-'|| MESSAGE_ENTITY.VALS;        
    end;

Java:

StructDescriptor structdesc = StructDescriptor.createDescriptor("T_MESSAGE_ENTITY", con);
        Clob clob1 = con.createClob();
        clob1.setString(1,"First paramter");
        Clob clob2 = con.createClob();
        clob2.setString(1,"Secound paramter");
        Object[] attributes = {clob1,clob2};
        STRUCT struct = new STRUCT(structdesc, con, attributes);        
        String CALL_PROC = "{call PROCESS_MESSAGE(?,?)}";
        CallableStatement  callableStatement = con.prepareCall(CALL_PROC);
        callableStatement.setObject(1, struct, Types.STRUCT);
        callableStatement.registerOutParameter(2, java.sql.Types.VARCHAR);
        callableStatement.executeUpdate();
        System.err.println(callableStatement.getString(2));

答案 1 :(得分:1)

您无需关闭/取消选中 Wrap Data Types 。另一种解决方法是使用以下代码

    if(obj instanceof weblogic.jdbc.wrapper.Clob) {
      weblogic.jdbc.wrapper.Clob clob = (weblogic.jdbc.wrapper.Clob)st1.getObject(2);
      **Clob oc = (oracle.sql.CLOB)clob.unwrap(Class.forName("oracle.sql.CLOB"));**
    }

答案 2 :(得分:0)

我已通过使用以下代码创建CLOB对象来解决此问题-

import React from "react"

class App extends React.Component {
    constructor() {
        super()
        this.state = {
            count: 0
        }
        this.handleClick = this.handleClick.bind(this)
    }
    
    handleClick() {
        this.setState(prevState => {
            return {
                count: prevState.count + 1
            }
        })
    }
    
    render() {
        return (
            <div>
                <h1>{this.state.count}</h1>
                <button onClick={this.handleClick}>Change!</button>
            </div>
        )
    }
}

export default App

您需要做的第二件事是取消选中已为其获取数据库连接的数据源的“包装数据类型”属性。即使在生产环境中,最好也不要取消选中此属性,因为这样做会提高应用程序的性能。

oracle.jdbc.OracleClob clobCols = (oracle.jdbc.OracleClob) conn.createClob();
clobCols.setString(1, "String value")