6

有谁知道我在这里做错了什么?我正在尝试将一个 blob(包含一个 pdf 以防万一)连同一些附加信息一起插入到 oracle 数据库中。我正在使用 PreparedStatement

代码:

public void saveReportErgebnis(int reportId, Date erzeugung, int archiv,
        Blob pdf, String kommentar) throws Exception {

    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    byte[] tmp = new byte[(int) pdf.length()];
    if(kommentar == null){
        kommentar = "";
    }

    SimpleDateFormat erstellungSdf = new SimpleDateFormat(
            "yyyy-MM-dd HH:mm:ss");

    try {
    pdf.getBinaryStream().read(tmp);

    oracle.sql.BLOB oracleBlob = new oracle.sql.BLOB((OracleConnection) getConnection(), tmp);
    PreparedStatement prepStmt = getRTTDBHandler()
            .createPreparedStatement(
                    "INSERT INTO reportergebnis(report_id, erzeugung, archiv, pdf, kommentar) VALUES (?,?,?,?,?)");
    System.out.println("debug 2 oracle");
        prepStmt.setInt(1, reportId);
        prepStmt.setString(2, formatDateString(erstellungSdf.format(erzeugung)));
        prepStmt.setInt(3, archiv);
        prepStmt.setBlob(4, oracleBlob);
        prepStmt.setString(5, kommentar);
        prepStmt.execute();
    } catch (Exception e) {
        e.printStackTrace();
        loghandler.error(e.toString());
        throw e;
    }

}

(formatCode 将 Date 放入正确的形式,例如返回:
date to_date('2013-04-15 09:34:38','yyyy-mm-dd hh24:mi:ss')

执行 PrepStatement 时,出现以下异常:

{java.lang.ArrayIndexOutOfBoundsException
        at java.lang.System.arraycopy(Native Method)
        at oracle.jdbc.driver.DatumBinder.bind(OraclePreparedStatement.java:18279)
        at oracle.jdbc.driver.OraclePreparedStatement.setupBindBuffers(OraclePreparedStatement.java:3137)
        at oracle.jdbc.driver.OraclePreparedStatement.processCompletedBindRow(OraclePreparedStatement.java:2355)
        at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3579)
        at oracle.jdbc.driver.OraclePreparedStatement.execute(OraclePreparedStatement.java:3685)
        at oracle.jdbc.driver.OraclePreparedStatementWrapper.execute(OraclePreparedStatementWrapper.java:1088)
        at com.nundp.mc.modules.regressionsTest.db.OracleRTTDBHandler.saveReportErgebnis(OracleRTTDBHandler.java:963)
        at com.nundp.mc.modules.regressionsTest.report.ReportController.executeReport(ReportController.java:237)
        at org.apache.jsp.jsp.modules.Testszenario.ReportHandler_jsp._jspService(ReportHandler_jsp.java:156)
        at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
        at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)
        at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
        at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:630)
        at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:535)
        at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:472)
        at org.apache.jasper.runtime.JspRuntimeLibrary.include(JspRuntimeLibrary.java:968)
        at org.apache.jsp.jsp.McFrame_jsp._jspService(McFrame_jsp.java:284)
        at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
        at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)
        at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
        at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
        at java.lang.Thread.run(Thread.java:619)}

我正在使用 Oracle 数据库 10g 版本 10.2.0.3.0。请帮忙!

4

5 回答 5

1

在我的应用程序中,我使用 aFile而不是 aBlob作为方法输入,并以这种方式完成了 BLOB 插入:

public void insertBlob(String filedesc, File file) {
    Connection con = DriverManager.getConnection(url, username, password);

    InputStream input = new FileInputStream(file);

    PreparedStatement pstmt = con.prepareStatement(
        "insert into schema.table values(?,?)");
    pstmt.setString(1, filedesc);
    pstmt.setBinaryStream(2, input);

    pstmt.execute();
}

也许你会需要一些try-catch,但我希望这会对你有所帮助。

于 2013-04-16T14:06:13.953 回答
0

尝试在 oracle.sql.BLOB 上使用 *createTemporary(yourConnection, false, oracle.sql.BLOB.DURATION_CALL)* 函数来创建您的实例。之后,只需使用 setBytes(...) 设置其内容。

于 2013-04-15T16:18:45.357 回答
0

一句话:prepStmt.setDate(2, erzeugung);更简单。

我本来期望一个简单的:

InputStream blobIS = pdf.getBinaryStream();
prepStmt.setBlob(4, blobIS, pdf.length());

... pdf.free();
于 2013-04-15T16:34:14.827 回答
0

对于未来的搜索者,这就是我解决 blob 问题的方法:

public void saveReportErgebnis(int reportId, Date erzeugung, int archiv,
        Blob pdf, String kommentar) throws Exception {

    byte[] tmp = new byte[(int) pdf.length()];
    if (kommentar == null) {
        kommentar = "";
    }

    try {
        pdf.getBinaryStream().read(tmp);
        PreparedStatement prepStmt = getRTTDBHandler()
                .createPreparedStatement(
                        "INSERT INTO reportergebnis(report_id, erzeugung, archiv, pdf, kommentar) VALUES (?,?,?,?,?)");
        prepStmt.setInt(1, reportId);
        Timestamp ts = new Timestamp(erzeugung.getTime());
        prepStmt.setTimestamp(2, ts);
        prepStmt.setInt(3, archiv);
        prepStmt.setBytes(4, tmp);
        prepStmt.setString(5, "'" + kommentar + "'");
        prepStmt.execute();
    } catch (Exception e) {
        e.printStackTrace();
        loghandler.error(e.toString());
        throw e;
    }
}

非常感谢大家的帮助。

于 2013-04-24T07:15:18.407 回答
0

我认为您必须在使用setBlob()之前进行一些卫生检查

  1. 检查数据库表中的参数数量
  2. 检查 blob 的位置。

但是,我宁愿建议您仅将 URl 存储在数据库中,而不是存储文件的二进制数据。

于 2013-04-17T07:13:27.460 回答