使用 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
包含您可以在上面看到的脚本,变量conn
是Connection
对象。
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】:好的,最终发现了问题,它需要是CallableStatement
和setEscapeProcessing(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
变量中,并创建一个 CallableStatement
或 Statement
以通过 JDBC 执行它。我不希望使用 JDBC 调用“Java Source”,我希望使用 JDBC 创建它。
哦,对不起,我不明白你想用 JDBC 执行 DDL。我的建议是某些工具更自然地适合某些任务:SQL*Plus 比 JDBC 更适合执行 DDL 脚本。如果您真的想使用 JDBC,我建议您从一个非常小的示例(一行类)开始,然后从那里开始。以上是关于使用 JDBC 在 Oracle 数据库上创建 Java的主要内容,如果未能解决你的问题,请参考以下文章
使用 JDBC 连接位于同一服务器上不同数据库中的 2 个 Oracle 表中的数据
无法使用 19.3 JDBC 驱动程序连接到 Oracle 19.3