oracle/plsql 的臨時表

1.臨時表分爲:

會話級臨時表:臨時表中的數據只在會話生命週期之中存在,當用戶退出會話結束的時候,Oracle自動清除臨時表中數據。

事務級臨時表:臨時表中的數據只在事務生命週期中存在。當一個事務結束(commit or rollback),Oracle自動清除臨時表中數據。

2.創建:

會話級:CREATE GOLBAL TEMPORARY TABLE  TEMP_TBL1 (RT_ID VARCHAR2(20),PAT_ID VARCHAR2(20)) ON  COMMIT PRESERVE ROWS ;

事務級:CREATE GOLBAL TEMPORARY TABLE  TEMP_TBL2 (RT_ID VARCHAR2(20),PAT_ID VARCHAR2(20)) ON  COMMIT DELETE ROWS ;

(紅色字體爲固定寫法,黑色字體爲自定義)

3.區別:

事務級的在sql中只要執行commit命令,則臨時表中的數據就被清空。

會話級的在執行完後,即當前訪問結束後,臨時表中的數據就被清空,如c#調用完存儲過程後,就會被清空。

4.相同點:

1. 臨時表中的數據只對當前Session有效,每個Session都有自己的臨時數據,並且不能訪問其它Session的臨時表中的數據。即:多個客戶端同時訪問服務器上的同一個臨時表時,並不能看到別的用戶的數據,也無法對其進行操作,但表是存在的。所以如果要創建臨時表,應先執行

     SELECT COUNT(*) INTO TEMP_TBL_COUNT FROM USER_TABLES T  WHERE T.TABLE_NAME = 'TEMP_TBL';

     (TEMP_TBL_COUNT 爲number型的變量,保存檢索出來的個數;TEMP_TBL爲創建的臨時表的名字。)

只有當TEMP_TBL_COUNT =0的時候才創建臨時表。

2. 當多個人同時使用的時候是無法刪除臨時表的,雖然多個用戶彼此看不到也無法操作對方的數據,但表還是同一個,只是各自有各自的session。如果採用實體表的話,要防止多個人同時操作同一個表,那在創建實體表的時候應多加一個session_id的字段,區別各個用戶。

3. EXECUTE IMMEDIATE:執行命令,因爲在存儲過程中無法直接執行,可以用該命令加上’要執行的命令‘來實現select,insert,delete等操作。如創建臨時表 

           EXECUTE IMMEDIATE ' CREATE GOLBAL TEMPORARY TABLE  TEMP_TBL1 (RT_ID VARCHAR2(20),PAT_ID VARCHAR2(20)) ON  COMMIT PRESERVE ROWSROWS ‘  ;

    COMMIT:提交命令,當用EXECUTE IMMEDIATE執行完後,對於insert和delete操作,要記得commit(事務級的臨時表不需要,因爲commit會清空其數據)。同時commit會導致事務級的臨時表的數據清空。

        4. 直接在在plsql中查看臨時表是看不到數據的,需要用遊標將其取出則可以看到。如:

  PROCEDURE TEMP_TBL_TEST(STR IN VARCHAR) IS
    CUR_A_CURSOR REF_CURSOR;
    V_C_RT_ID    VARCHAR(20);
    V_C_PAT_ID   VARCHAR(20);
  BEGIN
    OPEN CUR_A_CURSOR FOR 'SELECT * FROM TONG_TEMP_TBL';  //TONG_TEMP_TBL爲已經創建好的臨時表
      LOOP
      FETCH CUR_A_CURSOR
        INTO V_C_RT_ID, V_C_PAT_ID;
      EXIT WHEN CUR_A_CURSOR%NOTFOUND;
    END LOOP;
  END TEMP_TBL_TEST;

5. 舉例:

// 查找臨時表是否已經存在

SELECT COUNT(*)
      INTO TEMP_TBL_COUNT
      FROM USER_TABLES T
     WHERE T.TABLE_NAME = 'TONG_TEMP_TBL2';

    //如果臨時表不存在則創建事務級的臨時表
    IF TEMP_TBL_COUNT = 0 THEN
      EXECUTE IMMEDIATE 'CREATE GLOBAL TEMPORARY TABLE TONG_TEMP_TBL2(C_RT_ID VARCHAR2(20), C_PAT_ID VARCHAR2(20)) ON COMMIT DELETE ROWS';
    ELSE

      //如果臨時表存在則清空其數據,在這也可以利用執行commit;命令來清空。
      EXECUTE IMMEDIATE 'truncate TABLE TONG_TEMP_TBL2';
    END IF;
    COMMIT;

  //往臨時表中插入數據,在執行完後別忘了執行commit(會話級的臨時表需要);

EXECUTE IMMEDIATE 'INSERT INTO TONG_TEMP_TBL2 ( ' ||
                      'SELECT TONG_TEMP_TBL.C_RT_ID,
                          TONG_TEMP_TBL.C_PAT_ID 
                       FROM TONG_TEMP_TBL WHERE NOT EXISTS( SELECT  1 FROM( ' ||
                      C_FREE_WORD1 ||
                      ') T2 WHERE T2.C_RT_ID = TONG_TEMP_TBL.C_RT_ID AND T2.C_PAT_ID = TONG_TEMP_TBL.C_PAT_ID))';


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章