我正在尝试使用JDBC在oracle数据库上创建Java源对象。
我想要创建的来源如下:
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;
}
}
}
/
我尝试使用执行方法CallableStatement
,这给了我error: "Missing IN/OUT parameters"
当我尝试在普通Statement
对象上使用execute方法时,我得到错误:“
Non supported SQL92 token at position: 262"
任何人都知道我做错了什么?似乎无法在谷歌上找到任何东西。
编辑:
这是我用来尝试执行脚本的代码(String sql
包含您可以在上面看到的脚本,变量conn
是Connection
对象。
CallableStatement stat = conn.prepareCall(sql);
stat.setEscapeProcessing(false);
stat.execute();
如果我只使用Statement,那就是:
Statement stat = conn.createStatement();
stat.execute(sql);
答案 0 :(得分:7)
好的,最终发现了问题,需要CallableStatement
与setEscapeProcessing(false)
。
答案 1 :(得分: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('StackOverflow'));
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 /
StackOverflow