我的Web应用程序出现间歇性问题,经常需要打开位于数据库服务器上的文件作为常规操作的一部分。在绝大多数情况下,这个功能没有问题,但是,在看似随机的时间,相应的请求开始返回HTTP 400错误。弹出apache服务器会在一段时间内解决问题,但它总会在一天或最多一周内返回。
我在相关的pl / sql代码中添加了一些日志记录(不,不要跑掉!回来!),我已在下面列出以供参考:
declare
bl_blob blob;
bf_file bfile := bfilename(<directory that totally exists>, <file that totally exists>);
begin
dbms_lob.createTemporary(bl_blob, true);
dbms_lob.open(bf_file, dbms_lob.lob_readonly);
dbms_lob.open(bl_blob, dbms_lob.lob_readwrite);
dbms_lob.loadfromfile(bl_blob, bf_file, dbms_lob.getLength(bf_file));
dbms_lob.close(bf_file);
return bl_blob;
end;
事实证明400错误对应于以下ORA-22288错误:
file or LOB operation FILEOPEN failed
The program issued a command but the command length is incorrect
我的问题是,为什么操作会突然而且反复地开始错误输出以前可以打开同一个文件而没有问题?基础文件永远不会更改,只能以编程方式使用只读权限打开。
到目前为止,我所做的所有论坛挖掘工作大部分时间都取得了很大的成果,并将其打开并关闭了#34;解决方案,...是的。
非常感谢任何帮助。
答案 0 :(得分:1)
我不确定这是否正是您正在运行的代码,或者您是否已将其简化为SO。你的bfile基本上是一个指针,所以我不确定如果在你建立指针后在磁盘上修改了文件会发生什么。我也不确定这样的匿名块是否像SQL语句一样被解析和缓存。长话短说,试试这个:
declare
bl_blob blob;
bf_file bfile;
begin
bf_file := bfilename(<directory that totally exists>, <file that totally exists>);
dbms_lob.createTemporary(bl_blob, true);
dbms_lob.open(bf_file, dbms_lob.lob_readonly);
dbms_lob.open(bl_blob, dbms_lob.lob_readwrite);
dbms_lob.loadfromfile(bl_blob, bf_file, dbms_lob.getLength(bf_file));
dbms_lob.close(bf_file);
return bl_blob;
end;
答案 1 :(得分:0)
请尝试使用dbms_lob.getLength(bf_file)
,而不是使用DBMS_LOB.LOBMAXSIZE
来加载金额。这可能会有所帮助。
答案 2 :(得分:0)
您没有注意到(或者我没有看到)您的应用服务器的框架,但如果您有幸在您的应用服务器上运行Java,则可以简化您的代码很大。我不知道这是否能解决您的问题,但至少可以消除知道bfile长度的需要。
public void getFile (String oradir, String filename, String filesysdir) throws FileNotFoundException, IOException, SQLException, Exception {
CallableStatement s = this.conn.prepareCall("select bfilename(?,?) from dual");
s.setString(1, oradir);
s.setString(2, filename);
OracleResultSet r = (OracleResultSet) s.executeQuery();
if (r.next())
saveBFILE(r.getBFILE(1), filesysdir);
}
private void saveBFILE (BFILE b, String dir) throws FileNotFoundException, IOException, SQLException {
b.openFile();
InputStream s = b.getBinaryStream();
InputStreamReader r = new InputStreamReader(s);
String name = b.getName();
String path = dir == null ? name : dir + '/' + name;
System.out.println("creating " + name);
FileOutputStream w = new FileOutputStream(new File(path));
int nb;
byte[] ba = new byte[4096];
while ((nb = s.read(ba)) != -1)
w.write(ba, 0, nb);
w.close();
b.closeFile();
}