Oracle 中 MySQL 临时表的替代方案

发布于 2024-12-01 10:13:42 字数 278 浏览 1 评论 0原文

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

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

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

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

I noticed that the concept of temporary tables in these two systems is different, and I have a musing.. I have the following scenario in MySQL:

  1. Drop temporary table 'a' if exists
  2. Create temporary table 'a'
  3. Populate it with data through a stored procedure
  4. Use the data in another stored procedure

How can I implement the same scenario in Oracle? Can I (in one procedure preferable) create a temporary table, populate it, and insert data in another (non-temporary) table?

I think that I can use a (global) temporary table which truncates on commit, and avoid steps 1&2, but I need someone else's opinion too.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

假扮的天使 2024-12-08 10:13:42

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

如果您在执行 PL/SQL 计算时只需要一个临时位置来存储数据,则 PL/SQL 集合比 Oracle 中的临时表更常用。这样,您就不需要将数据从 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 中真正需要临时表的次数。

In Oracle, you very rarely need a temporary table in the first place. You commonly need temporary tables in other databases because those databases do not implement multi-version read consistency and there is the potential that someone reading data from the table would be blocked while your procedure runs or that your procedure would do a dirty read if it didn't save off the data to a separate structure. You don't need global temporary tables in Oracle for either of these reasons because readers don't block writers and dirty reads are not possible.

If you just need a temporary place to store data while you perform PL/SQL computations, PL/SQL collections are more commonly used than temporary tables in Oracle. This way, you're not pushing data back and forth from the PL/SQL engine to the SQL engine and back to the PL/SQL engine.

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;

You can create a global temporary table (outside of the procedure) and use the global temporary table inside your procedure just as you would use any other table. So you can continue to use temporary tables if you so desire. But I can count on one hand the number of times I really needed a temporary table in Oracle.

罪歌 2024-12-08 10:13:42

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

如果您决定坚持使用常规表,您可能需要使用@Johan 给出的建议,并使其

ALTER TABLE <table name> NOLOGGING;

执行速度更快一些。

You are right, temporary tables will work work you.

If you decide stick with regular tables you may want to use the advice @Johan gave, along with

ALTER TABLE <table name> NOLOGGING;

to make this perform a bit faster.

半城柳色半声笛 2024-12-08 10:13:42

我认为您使用的方案没有问题。
请注意,它不一定是临时表,您也可以使用某种内存表。

通过照常创建一个表来执行此操作,然后执行

ALTER TABLE <table_name> CACHE;  

此操作将优先将该表存储在内存中。

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

只需执行以下操作:

  1. 通过存储过程使用数据填充缓存表

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

I see no problem in the scheme your are using.
Note that it doesn't have to be a temp-table, you can use a sort of kind of memory table as well.

Do this by creating a table as usual, then do

ALTER TABLE <table_name> CACHE;  

This will prioritize the table for storage in memory.

As long as you fill and empty the table in short order you don't need to do step 1 & 2.
Remember the cache modifier is just a hint. The table still ages in the cache and will be pushed out of memory eventually.

Just do:

  1. Populate cache-table with data through a stored procedure

  2. Use the data in another stored procedure, but don't wait to long.
    2a. Clear the data in the cache table.

稍尽春風 2024-12-08 10:13:42

在你的MySQL版本中,我没有看到删除表a的第5步。因此,如果您想要或不介意表中的数据持久存在,您也可以使用物化视图并只需按需刷新即可。使用物化视图,您不需要管理任何 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;

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

In your MySQL version, I didn't see a step 5 to drop the table a. So, if you want or don't mind having the data in the table persist you could also use a materialized view and simply refresh on demand. With a materialized view you do not need to manage any INSERT statements, just include the 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 ....;

Then in your other stored procedure, call:

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

That said, a global temporary table will work as well, but you manage the insert and exceptions.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文