Oracle中MySQL临时表的替代方案



我注意到这两个系统中临时表的概念是不同的,我有一个思考…我在MySQL中有以下场景:

    删除临时表a 创建临时表'a'
  1. 通过存储过程填充数据
  2. 在另一个存储过程中使用数据

如何在Oracle中实现相同的场景?我可以(最好在一个过程中)创建一个临时表,填充它,然后在另一个(非临时)表中插入数据吗?

我认为我可以使用一个(全局)临时表,它在提交时截断,并避免步骤1&2,但我也需要别人的意见。

在Oracle中,首先很少需要临时表。您通常需要其他数据库中的临时表,因为这些数据库没有实现多版本读取一致性,并且在您的过程运行时,可能会有人从表中读取数据被阻塞,或者如果您的过程没有将数据保存到单独的结构中,则可能会执行脏读取。由于以上两种原因,在Oracle中不需要全局临时表,因为读不会阻塞写,也不可能进行脏读。

如果你只是在执行PL/SQL计算时需要一个临时的地方来存储数据,那么在Oracle中PL/SQL集合比临时表更常用。这样,您就不会将数据从PL/SQL引擎推到SQL引擎,再推回PL/SQL引擎。

CREATE PROCEDURE do_some_processing
AS
  TYPE emp_collection_typ IS TABLE OF emp%rowtype;
  l_emps emp_collection_type;
  CURSOR emp_cur
      IS SELECT *
           FROM emp;
BEGIN
  OPEN emp_cur;
  LOOP
    FETCH emp_cur 
     BULK COLLECT INTO l_emps
    LIMIT 100;
    EXIT WHEN l_emps.count = 0;
    FOR i IN 1 .. l_emps.count
    LOOP
      <<do some complicated processing>>
    END LOOP;
  END LOOP;
END;

您可以创建一个全局临时表(在过程外部),并在过程内部使用全局临时表,就像使用任何其他表一样。因此,如果您愿意,可以继续使用临时表。但是,在Oracle中,我真的需要临时表的次数屈指可数。

你是对的,临时表将为你工作。

如果你决定坚持使用常规表,你可能需要使用@Johan给出的建议,以及

ALTER TABLE <table name> NOLOGGING;

我看你使用的方案没有问题。
注意,它不一定是一个临时表,您也可以使用某种类型的内存表。

像往常一样创建一个表,然后执行

ALTER TABLE <table_name> CACHE;  

这将优先考虑表在内存中的存储。

只要在短时间内填充空表,就不需要执行第1步&2。
记住cache修饰符只是一个提示。表仍然在缓存中老化,最终将被推出内存。

只做:

  1. 通过存储过程向cache表中填充数据

  2. 在另一个存储过程中使用数据,但不要等待太久。2 a。清除cache表中的数据

在你的MySQL版本中,我没有看到第5步删除表a。所以,如果你想要或不介意保留表中的数据,你也可以使用物化视图并按需刷新。对于物化视图,您不需要管理任何INSERT语句,只需包含SQL:

CREATE MATERIALIZED VIEW my_mv
NOCACHE -- NOCACHE/CACHE: Optional, cache places the table in the most recently used part of the LRU blocks
BUILD IMMEDIATE  -- BUILD DEFERRED or BUILD IMMEDIATE
REFRESH ON DEMAND
WITH PRIMARY KEY -- Optional: creates PK column
AS
SELECT * 
FROM ....;

然后在其他存储过程中调用:

BEGIN   
    dbms_mview.refresh ('my_mv', 'c'); -- 'c' = Complete
END;

也就是说,全局临时表也可以工作,但是您需要管理插入和异常。

相关内容

  • 没有找到相关文章

最新更新