当前位置: 首页 > 面试题库 >

如何以可靠的方式编写/更新Oracle Blob?

锺离飞尘
2023-03-14
问题内容

我正在尝试在blob列中编写和更新pdf文档,但是我只能够更新blob,仅写入比先前存储的数据更多的数据。如果尝试使用较小的文档数据更新blob列,则只会得到损坏的pdf。

首先,blob列已使用empty_blob()函数进行了初始化。我在下面编写了示例Java类来测试此行为。我第一次使用“ true”作为 main
方法的第一个参数运行它,因此在第一行中存储了大约31kB的文档,在第二行中存储了278kB的文档。然后,我以’false’作为参数运行它,通过这种方式应该交换两行以交换文档。结果是,仅当我写入的数据多于现有数据时,我才能获得正确的结果。

如何编写一种以可靠的方式写入和更新Blob而不担心二进制数据大小的方法?

import static org.apache.commons.io.IOUtils.copy;

import java.io.FileInputStream;
import java.io.OutputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import oracle.jdbc.OracleDriver;
import oracle.jdbc.OracleResultSet;
import oracle.sql.BLOB;

import org.apache.commons.lang.ArrayUtils;
/**
 * Prerequisites:
 * 1) a table named 'x' must exists [create table x (i number, j blob);] 
 * 2) that table should have two columns [insert into x (i, j) values (1, empty_blob()); insert into x (i, j) values (2, empty_blob()); commit;]
 * 3) download lsp.pdf from http://www.objectmentor.com/resources/articles/lsp.pdf
 * 4) download dotguide.pdf from http://www.graphviz.org/Documentation/dotguide.pdf
 */
public class UpdateBlob {
    public static void main(String[] args) throws Exception {
        processFiles(new String[]{"lsp.pdf", "dotguide.pdf"}, Boolean.valueOf(args[0]));
    }

    public static void processFiles(String [] fileNames, boolean forward) throws Exception {
      if(!forward){
        ArrayUtils.reverse(a);
      }
      int idx = 1;
      for(String fname : fileNames){
        insert(idx++, fname);
      }
  }

    private static void insert(int idx, String fname) throws Exception{
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            DriverManager.registerDriver(new OracleDriver());
            conn = DriverManager.getConnection("jdbc:oracle:thin:@"+db+":"+port+":"+sid, user, pwd);
            ps = conn.prepareStatement("select j from x where i = ? for update");
            ps.setLong(1, idx);

            rs = ps.executeQuery();

            if (rs.next()) {
                FileInputStream instream = new FileInputStream(fname);
                BLOB blob = ((OracleResultSet)rs).getBLOB(1);
                OutputStream outstream = blob.setBinaryStream(1L);
                copy(instream, outstream);
                instream.close();
                outstream.close();
            }
            rs.close();
            ps.close();
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
            throw new Exception(e);
        }
    }
}

Oracle版本:11.1.0.7.0-64位

我什至没有使用Oracle的专用JDBC API(例如上例)就尝试了标准的JDBC API,但没有成功。


问题答案:

这要容易得多:

PreparedStatement pstmt =
  conn.prepareStatement("update blob_table set blob = ? where id = ?");
File blob = new File("/path/to/picture.png");
FileInputStream in = new FileInputStream(blob);

// the cast to int is necessary because with JDBC 4 there is 
// also a version of this method with a (int, long) 
// but that is not implemented by Oracle
pstmt.setBinaryStream(1, in, (int)blob.length());

pstmt.setInt(2, 42);  // set the PK value
pstmt.executeUpdate();
conn.commit();
pstmt.close();

使用INSERT语句时,其工作原理相同。不需要empty_blob()第二条更新语句。



 类似资料:
  • 我有一小段代码。我想用更好的方式写它,用更少的嵌套支票。我怎样才能实现呢? 有没有什么简洁的方法可以让我用Java 8重写上面的代码呢?

  • 我刚开始使用Spring data mongob,但我只是被卡住了,如何使用mongo存储库编写基于json的嵌入式文档查询。 我的数据库看起来像 我想更新基于顶级文档id的子类型,我必须更新具有id 5565ad670cf25cbd975ab2d2的子类型的首选项,如何为此编写查询?

  • 问题内容: 我正在尝试以编程方式在Java中创建新的密钥库。如下代码: 引发未初始化的KeyStore异常。 问题答案: 创建密钥库后,需要将其加载。load方法要求读取FileInputStream,但是如果您提供一个null,则将加载一个空的KeyStore。 看到这个链接

  • 问题内容: 我有一个,我使用Xcode Interface Builder设置了约束。 现在,我需要以编程方式更新该高度常数。 有一个类似的功能,但我不知道如何使用它。 问题答案: 从“界面”构建器中选择高度约束,然后选择其高度。因此,当您想更改视图的高度时,可以使用以下代码。 方法是的实例方法。以编程方式设置约束时,这将很有帮助。它更新视图的约束。有关更多详细信息,请单击此处。

  • 问题内容: 我似乎找不到不使用来使用react- router更新查询参数的方法。似乎没有注册查询参数,而且似乎也不能将查询对象或任何内容作为第二个参数传递。 如何从更改URL ,以在反应路由器没有使用? 而且是一个真正的函数来监听查询变化的唯一途径?为什么没有自动检测到查询更改并对参数更改做出反应? 问题答案: 在中,您可以指定查询参数。例如, 要么 您可以查看此存储库以获取有关使用的其他示例

  • 我有一个,我使用Xcode Interface Builder设置约束。 现在,我需要以编程方式更新该实例的高度常量。 有一个函数类似,但我不知道如何使用它。