使用 JDBC 在 Oracle 数据库上创建 Java

Posted

技术标签:

【中文标题】使用 JDBC 在 Oracle 数据库上创建 Java【英文标题】:Create Java on Oracle database with JDBC 【发布时间】:2013-04-22 07:35:50 【问题描述】:

我正在尝试 源对象。

我要创建的源如下:

create or replace and resolve java source named "BlobIO" as package dbjava;


import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.io.*;


public class BlobIO 

    /**
     * Stores a blob into a local file (or even UNC-path)
     * @param blob The blob locator that should be stored in a file
     * @param filename The filename to write to
     * @param bufferSize The buffer size for data transfer
     * @return 1 if successful, 0 if failed
     */
    public static int blobToFile(java.sql.Blob blob, String filename, int bufferSize)
    
        OutputStream os = null;
        InputStream is = null;
        boolean fail = true;
        try 

            is = blob.getBinaryStream();
            os = new FileOutputStream(filename);
            int amountRead = 0;
            byte[] buffer = new byte[bufferSize];
            while ((amountRead = is.read(buffer, 0, buffer.length)) != -1) 
                os.write(buffer, 0, amountRead);
            
            is.close();
            os.flush();
            os.close();
            fail = false;
         catch (IOException ex) 
            new File(filename).delete();
            System.err.println("Could not store blob to file.");
            System.err.println("File : " + filename);
            System.err.println("Reason : " + ex.getClass().getName() + " : " + ex.getMessage());
            fail = true;
         catch (SQLException ex) 
            new File(filename).delete();
            System.err.println("Could not store blob to file.");
            System.err.println("File : " + filename);
            System.err.println("Reason : " + ex.getClass().getName() + " : " + ex.getMessage());
            fail = true;
         finally 
            try is.close(); catch (Exception ex) 
            try os.flush(); catch (Exception ex) 
            try os.close(); catch (Exception ex) 
        
        return fail? 0:1;
    

    /**
     * Stores a blob into a local file (or even UNC-path)
     * @param query The query that should select ONLY the blob field
     * @param filename The filename to write to
     * @param bufferSize The buffer size for data transfer
     * @return 1 if successful, 0 if failed
     */
    public static int blobToFile(String query, String filename, int bufferSize) 
        try 
            Connection conn = DriverManager.getConnection("jdbc:default:connection:");
            Statement stmt = conn.createStatement();
            ResultSet rset = stmt.executeQuery(query);
            InputStream is;


            if (rset.next())
            
                int ret = blobToFile(rset.getBlob(1), filename, bufferSize);
                if (rset.next())
                
                    new File(filename).delete();
                    System.err.println("Could not store blob to file.");
                    System.err.println("Blob query : " + query);
                    System.err.println("File : " + filename);
                    System.err.println("Reason : too many rows");
                    rset.close();
                    stmt.close();
                    return 0;
                 else 
                    rset.close();
                    stmt.close();
                    return ret;
                
             else 
                System.err.println("Could not store blob to file.");
                System.err.println("Blob query : " + query);
                System.err.println("File : " + filename);
                System.err.println("Reason : no records retrieved by query");
                rset.close();
                stmt.close();
                return 0;
            
         catch (Exception e) 
            System.err.println(e.getMessage());
            return 0;
        

    


/

我尝试使用 execute 方法使用CallableStatement,这给了我error: "Missing IN/OUT parameters" 当我尝试在普通 Statement 对象上使用 execute 方法时,我收到错误消息:“

Non supported SQL92 token at position: 262"

有人知道我做错了什么吗?谷歌好像也找不到任何东西。

编辑: 这是我用来尝试执行脚本的代码(字符串sql 包含您可以在上面看到的脚本,变量connConnection 对象。

CallableStatement stat = conn.prepareCall(sql);
stat.setEscapeProcessing(false);
stat.execute();

如果我尝试只使用 Statement 它是这样的:

Statement stat = conn.createStatement();
stat.execute(sql);

【问题讨论】:

能否请您发布您用于创建 Java 对象的完整代码(不仅是此 Java 对象本身的源代码)? @FrankSchmitt : 这是完整的代码,这是我要执行的脚本,你的意思是 JDBC 的 Java 代码吗? @FrankSchmitt 我已经添加了这两部分。 【参考方案1】:

好的,最终发现了问题,它需要是CallableStatementsetEscapeProcessing(false)

【讨论】:

你是我的救星。 我试过这个,它适用于一些源文件,但对于其他 Missing IN or OUT parameter at index:: 1 却失败了。然后我发现了这个:***.com/a/21882264/501399,它适用于任何文件。所以它应该是Statement,而不是CallableStatement【参考方案2】:

请发布一个完整的完整示例。您的代码正在运行,以下是我的11.1.0.7.0 db 上的结果。首先是设置:

SQL> create or replace directory TMP as '/tmp';

Directory created

SQL> CREATE TABLE testBlob (a BLOB);

Table created

SQL> INSERT INTO testBlob VALUES (utl_raw.cast_to_raw('***'));

1 row inserted

第一个函数:

SQL> CREATE OR REPLACE FUNCTION blob2File(p_blob BLOB,
  2                                       p_path VARCHAR2,
  3                                       p_buffer NUMBER)
  4    RETURN NUMBER AS
  5  LANGUAGE JAVA NAME
  6     'dbjava.BlobIO.blobToFile(java.sql.Blob,
  7                               java.lang.String,
  8                               int) return int';
  9  /

Function created

SQL> DECLARE
  2     l_blob   BLOB;
  3     l_return INT;
  4  BEGIN
  5     SELECT * INTO l_blob FROM testBlob;
  6     l_return := blob2File(l_blob, '/tmp/test.blob', 1024);
  7     dbms_output.put_line(l_return);
  8  END;
  9  /

1

对于第二个功能:

SQL> CREATE OR REPLACE FUNCTION queryBlob2File(p_query VARCHAR2,
  2                                            p_path VARCHAR2,
  3                                            p_buffer NUMBER) RETURN NUMBER AS
  4  LANGUAGE JAVA NAME
  5     'dbjava.BlobIO.blobToFile(java.lang.String,
  6                               java.lang.String,
  7                               int) return int';
  8  /

Function created

SQL> DECLARE
  2     l_query  VARCHAR2(1000);
  3     l_return INT;
  4  BEGIN
  5     l_query := 'SELECT * FROM testBlob';
  6     l_return := queryBlob2File(l_query, '/tmp/test.blob', 1024);
  7     dbms_output.put_line(l_return);
  8  END;
  9  /

1

PL/SQL procedure successfully completed

您可以使用UTL_FILE 包直接在PL/SQL 中处理文件:

SQL> DECLARE
  2     l_file utl_file.file_type;
  3     l_line VARCHAR2(1024);
  4  BEGIN
  5     l_file := utl_file.fopen(location => 'TMP',
  6                              filename => 'test.blob',
  7                              open_mode => 'R');
  8     utl_file.get_line(l_file, l_line);
  9     dbms_output.put_line(l_line);
 10     utl_file.fclose(l_file);
 11  END;
 12  /

***

【讨论】:

我知道我的代码正在运行,当我使用 sqlplus 执行脚本时,它会被创建,但当我使用 JDBC 运行脚本时不会。 如何从jdbc调用数据库java源?请发布一个 THOROUGH 示例。我向您展示了如何从 PL/SQL 调用它。由于您可以从jdbc 调用 PL/SQL 脚本,所以我看不出问题出在哪里! 我在开始的帖子中说过,我将整个脚本放在 java String 变量中,并创建一个 CallableStatementStatement 以通过 JDBC 执行它。我不希望使用 JDBC 调用“Java Source”,我希望使用 JDBC 创建它。 哦,对不起,我不明白你想用 JDBC 执行 DDL。我的建议是某些工具更自然地适合某些任务:SQL*Plus 比 JDBC 更适合执行 DDL 脚本。如果您真的想使用 JDBC,我建议您从一个非常小的示例(一行类)开始,然后从那里开始。

以上是关于使用 JDBC 在 Oracle 数据库上创建 Java的主要内容,如果未能解决你的问题,请参考以下文章

通过 JDBC (oracle) 创建触发器

使用 JDBC 连接位于同一服务器上不同数据库中的 2 个 Oracle 表中的数据

无法使用 19.3 JDBC 驱动程序连接到 Oracle 19.3

JDBC连接Oracle

oracle数据库,怎么查库名,我要用JDBC连接?域名+端口+库名,但是我不知道我电脑上的ORACLE的库名是啥

Android Oracle 数据库 JDBC6