间歇性 ORA-22288 错误 - 命令长度不正确
Posted
技术标签:
【中文标题】间歇性 ORA-22288 错误 - 命令长度不正确【英文标题】:Intermittent ORA-22288 error - command length incorrect 【发布时间】:2014-09-18 12:47:28 【问题描述】:我的 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
我的问题是,为什么该操作会突然、反复地开始出错,指出以前可以毫无问题地打开同一个文件?底层文件永远不会更改,只会以只读权限以编程方式打开。
到目前为止,我所做的所有论坛挖掘都产生了一系列“关闭再打开”的解决方案,其中......是的。
非常感谢任何帮助。
【问题讨论】:
打开的文件太多?某处缺少close
?
看起来 Oracle 可能只是从操作系统传递了一个错误。谷歌搜索“程序发出命令但命令长度不正确”让我相信这是一个 Windows 问题。可以添加主机操作系统和操作系统版本吗?
@JonHeller 是的,我读过很多论坛帖子都这么说,尽管我还没有看到任何具体提及相关的根本原因。无论如何,这里是操作系统细节:Windows Server 2003 x64 SP 2
仅用于调查:捕获异常并打印堆栈跟踪 (dbms_utility.format_error_backtrace
) 以了解究竟是哪一行引发了错误。并将整个事情包装成循环以重试一次或两次 - 了解立即重试是否有效可能很有用。
你也应该有dbms_lob.close(bl_blob);
吗?您打开了 2 个对象,但只关闭了一个。
【参考方案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;
【讨论】:
大多数人应该考虑匿名 PL/SQL 块语句,就像任何其他类型的 SQL 语句一样。您不能从使用匿名 PL/SQL 块解析的游标中获取,但它们的游标必须像任何其他游标一样通过 PARSE 和 EXEC dbcall 代码。【参考方案2】:请尝试使用DBMS_LOB.LOBMAXSIZE
,而不是使用dbms_lob.getLength(bf_file)
作为要加载的数量。这可能会有所帮助。
【讨论】:
【参考方案3】:您没有注意到(或者我没有看到)您的应用服务器的框架,但是如果您有幸在您的应用服务器上运行 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();
【讨论】:
以上是关于间歇性 ORA-22288 错误 - 命令长度不正确的主要内容,如果未能解决你的问题,请参考以下文章
间歇性`错误:无法打开显示:localhost:10.0`与Vagrant