2011-09-29 90 views
3
  1. 在存儲過程中創建一個臨時表,例如'#Temp'。
  2. 使用select語句將值插入'Temp'表中,例如。插入到#Temp從僱員中選擇*。
  3. 現在從此Temp表中提取數據,例如。選擇* from #Temp其中#Temp.Id = @id &等等。

如何在中做到這一點在Oracle裏面存儲過程Oracle中臨時表的替代方案

+0

可能重複http://stackoverflow.com/questions/2918466/ways-to-avoid-global-temp-tables -in-oracle) – APC

回答

15

您試圖解決的業務問題是什麼?極少數情況下,您需要在Oracle中使用臨時表。你爲什麼不乾脆

SELECT * 
    FROM employees 
WHERE id = p_id_passed_in; 

在其他的數據庫中,你經常創建臨時表,因爲讀者,所以你想,以避免阻塞任何其他會話創建數據的單獨副本阻止作家。然而,在Oracle中,讀者不會阻止編寫者,因此通常不需要保存單獨的數據副本。

在其他數據庫中,您將創建臨時表,因爲您不想執行髒讀操作。但是,Oracle不允許髒讀。多版本讀取一致性意味着Oracle將始終向您顯示在查詢開始時存在的數據(或者如果您已經設置了可序列化的事務隔離級別,則事務開始)。所以不需要創建一個臨時表來避免髒讀。

如果你真的想在Oracle中使用臨時表,你不會動態地創建表。在創建存儲過程之前,您將創建一個全局臨時表。表結構對於所有會話都是可見的,但數據僅對插入它的會話可見。您可以在過程中填充臨時表,然後查詢表。類似於

CREATE GLOBAL TEMPORARY TABLE temp_emp (
    empno number, 
    ename varchar2(10), 
    job varchar2(9), 
    mgr number, 
    sal number(7,2) 
) 
ON COMMIT PRESERVE ROWS; 

CREATE OR REPLACE PROCEDURE populate_temp_emp 
AS 
BEGIN 
    INSERT INTO temp_emp(empno, 
         ename, 
         job, 
         mgr, 
         sal) 
    SELECT empno, 
      ename, 
      job, 
      mgr, 
      sal 
     FROM emp; 
END; 
/

SQL> begin 
    2 populate_temp_emp; 
    3 end; 
    4/

PL/SQL procedure successfully completed. 

SQL> select * 
    2 from temp_emp; 

    EMPNO ENAME  JOB    MGR  SAL 
---------- ---------- --------- ---------- ---------- 
     7623 PAV  Dev 
     7369 smith  CLERK   7902  800 
     7499 ALLEN  SALESMAN  7698  1600 
     7521 WARD  SALESMAN  7698  1250 
     7566 JONES  MANAGER   7839  2975 
     7654 MARTIN  SALESMAN  7698  1250 
     7698 BLAKE  MANAGER   7839  2850 
     7782 CLARK  MANAGER   7839  2450 
     7788 SCOTT  ANALYST   7566  3000 
     7839 KING  PRESIDENT     5000 
     7844 TURNER  SALESMAN  7698  1500 
     7876 ADAMS  CLERK   7788  1110 
     7900 SM0  CLERK   7698  950 
     7902 FORD  ANALYST   7566  3000 
     7934 MILLER  CLERK   7782  1300 
     1234 BAR 

16 rows selected. 

正如我所說,雖然在Oracle中實際想要使用臨時表是非常不尋常的。

+1

+1一個非常全面的解釋和答案 – Ollie

+1

我很感謝你的努力來回答我的問題,但它不是我所期待的。簡而言之,我需要在Oracle中使用臨時表INSIDE存儲過程的替代邏輯。 – nylon610

+0

@ nylon610 - 你能解釋爲什麼你不能使用全局臨時表嗎?使用動態SQL在存儲過程中創建對象在技術上是可行的,但這種額外的複雜性是非常值得的。特別是在多用戶系統中,因爲在Oracle中不可能有一個範圍限於會話的對象。 –