【问题标题】:PHP problem with selecting from Oracle global temporary table从 Oracle 全局临时表中选择的 PHP 问题
【发布时间】:2011-02-15 10:55:15
【问题描述】:

我有一个“ON COMMIT DELETE ROWS”的 Oracle 全局临时表。

我有一个循环,其中我:

  • 插入到全局临时表
  • 从全局临时表中选择(后处理)
  • 提交,以便在循环的下一次迭代之前清除表

通过调用 oci_execute($stmt, OCI_DEFAULT) 完成插入。通过调用 oci_fetch_all($stmt, $result, 0, -1, OCI_FETCHSTATEMENT_BY_ROW | OCI_ASSOC) 进行检索。之后,提交:oci_commit()。

问题是检索有时会起作用,有时我会遇到以下错误之一:

  • ORA-08103:对象不再存在
  • ORA-01410: 无效的 ROWID

好像会话无法“看到”它之前插入的记录。

您知道是什么原因造成的吗?

谢谢。

【问题讨论】:

    标签: php sql oracle


    【解决方案1】:

    您是否使用连接池?如果是这样,那么可能是在不同的会话中执行不同的调用。

    更好的解决方案是使用单个 PL/SQL 过程填充临时表并在单个调用中返回结果集。然后提出了一个更好的解决方案:完全取消临时表。

    Oracle 中很少有需要使用临时表的情况。大多数事情都可以通过纯 SQL 或批量收集到嵌套表中来解决。在插入和随后的选择之间,您对临时表中的数据进行了哪些实际操作?

    编辑

    临时表会影响性能 - 将行写入磁盘。 PL/SQL 集合保留在(会话)内存中,因此速度更快。当然,因为它们在会话内存中,它们不会解决连接池的问题。

    您是否因为不想一举将 200,000 行传递给您的 PHP 而需要对数据进行分块?如果我想进一步帮助你,我想我需要更多的背景信息。

    【讨论】:

    • 感谢您的出色回复。是的,我正在使用连接池,所以这可能确实是问题所在。实际上,在 INSERT 和 SELECT 之前没有进行任何处理。处理本身就是非常庞大和复杂的 SELECT 语句。检索到的数据最多可以有 200 000 条记录——正是由于这个事实,我决定使用全局临时表。将这么多数据存储在嵌套表中是否明智?还是从 Oracle 的角度来看,在内存使用方面没有太大区别?
    • 再次感谢。实际上,原始表有数百万条记录。在循环的每次迭代中,我必须处理来自该表的大约 200 000 条记录。我不想在原始表上使用我的复杂查询,所以我将这 20 万条记录提取到全局临时表中,这样我就可以在这个块上使用我的查询。如果您建议,我可以将此块存储在嵌套表中(通过 BULK COLLECT 收集)我只担心 PGA 内存使用情况。
    猜你喜欢
    • 1970-01-01
    • 2010-09-12
    • 2017-10-02
    • 2023-03-27
    • 1970-01-01
    • 1970-01-01
    • 2016-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多