【问题标题】:Global temporary tables getting data from different session in Oracle全局临时表从 Oracle 中的不同会话获取数据
【发布时间】:2010-05-26 16:09:52
【问题描述】:

我们在 Oracle 中有一个使用 global temporary tables 的存储过程。在我们的大多数其他存储过程中,我们首先要做的是从全局临时表中删除数据。但是,在少数存储过程中,我们没有delete's

除了添加删除语句之外,还有其他选择吗?是否可以在服务器端执行某些操作以在运行该 SP 时从这些临时表中强制删除数据?

GTT 使用 ON COMMIT PRESERVE ROWS; 定义

【问题讨论】:

    标签: oracle


    【解决方案1】:

    我认为您的标题具有误导性:问题不是“从不同会话中获取数据”,而是重复使用同一个会话。终止会话总是刷新临时表:

    SQL> conn apc
    Enter password:
    Connected.
    
    SQL> create global temporary table tmp_23 (username varchar2(30))
      2  on commit preserve rows
      3  /
    
    Table created.
    
    SQL> insert into tmp_23 values (user)
      2  /
    
    1 row created.
    
    SQL> commit
      2  /
    
    Commit complete.
    
    SQL> select * from tmp_23
      2  /
    
    USERNAME
    ------------------------------
    APC
    
    SQL> conn apc
    Enter password:
    Connected.
    SQL> select * from tmp_23
      2  /
    
    no rows selected
    
    SQL>
    

    除了删除截断之外,无法从会话中刷新具有 PRESERVE ROWS 的临时表。无法按照您建议的方式注释存储过程。因此,恐怕如果您遇到描述的问题,您将不得不硬着头皮将 DELETE(或 TRUNCATE)调用添加到您的程序中。或者用 DELETE ROWS 定义表;但这可能不适合您的处理。

    顺便说一句,您似乎在大量使用临时表。这在 Oracle 系统中是不寻常的,因为临时表是相对昂贵的对象(所有这些写入磁盘),并且通常有一种更高效的方式来处理事物:例如在 PL/SQL 集合中缓存数据或仅使用 SQL。来自非 Oracle 背景(尤其是 SQL Server)的开发人员经常过度使用临时表,因为他们已经习惯了这种工作方式。

    【讨论】:

    • 感谢您的详细解释。我们来自应用服务器的连接只有 8 个(我们的用户群很大),所以连接池让同一个会话被过度使用。我认为增加应用服务器连接会降低出现此类问题的可能性,但为了安全起见,删除总是好的
    • @Omnipresent - 是的,我想知道您是否使用了连接池。当应用程序的其余部分是无状态的时,数据库中状态的持久性可能是一个真正的问题。
    • 根据您的经验,摆脱临时表的最佳方法是什么。我们刚刚转换为 oracle 并正在大量使用它们。您提到了集合,我对 oracle 连接不太熟悉,但是游标呢?游标和集合有同样的好处吗?
    • @Omnipresent - 我认为这是一个全新的问题
    猜你喜欢
    • 2017-10-02
    • 2023-03-27
    • 1970-01-01
    • 2011-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-02
    • 1970-01-01
    相关资源
    最近更新 更多