MySQL的臨時表我注意到,臨時表在這兩個系統的概念是不同的,我有一個沉思..我有在MySQL以下情形:替代在Oracle
- 刪除臨時表「A」,如果存在
- 創建臨時表「A」
- 填充數據通過存儲過程
- 使用數據在另一個存儲過程
我如何能實現在Oracle中相同的情況下?我可以(在一個過程中最好)創建臨時表,填充它,並在另一個(非臨時)表中插入數據?
我認爲我可以使用在提交時截斷的(全局)臨時表,並避免步驟1 & 2,但我也需要其他人的意見。
MySQL的臨時表我注意到,臨時表在這兩個系統的概念是不同的,我有一個沉思..我有在MySQL以下情形:替代在Oracle
我如何能實現在Oracle中相同的情況下?我可以(在一個過程中最好)創建臨時表,填充它,並在另一個(非臨時)表中插入數據?
我認爲我可以使用在提交時截斷的(全局)臨時表,並避免步驟1 & 2,但我也需要其他人的意見。
在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中的臨時表的次數。
我看到你正在使用的方案沒有問題。
請注意,它不必是臨時表,也可以使用某種類型的內存表。
通過創建一個表像往常一樣做,那麼做
ALTER TABLE <table_name> CACHE;
這將優先表存儲在內存中。
只要您填寫和空在短期內表你不需要做第1步 記住cache
改性劑僅是一種暗示。該表仍然在緩存中老化,最終會被推出內存。
只要做到:
填充緩存表數據通過存儲過程
使用在另一個存儲過程中的數據,但不要等待很長時間。 2a。清除緩存表中的數據。
你是對的,臨時表會工作的你。
如果您決定堅持使用常規的表,你可能要沿着使用建議@Johan了,與
ALTER TABLE <table name> NOLOGGING;
,使這個執行快一點。
在你的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;
這就是說,全局臨時表會也可以工作,但是您可以管理插入和異常。
如果我使用第二個存儲過程中的數據,而不是等待太久,但緩存表有很多數據,它會在內存中,直到使用它的過程完成? –
@Moondowner,它可能會,但它可能會推出很多其他數據,所以它確實取決於哪種方法更加加速您的應用程序。只有你可以測試它。 – Johan