间歇性 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

Microsoft SQL Server 2008 上使用 TABLOCK、XLOCK 命令的间歇性死锁

wm命令用法及LCD显示图标大小不正常时解决的方法

win7不正常开关机,系统恢复选项

linux命令结尾加正斜杠与不正加斜杠的区别

Bigquery API 间歇性返回 http 错误 400“错误请求”