2015-11-29 18 views
0

我想用數據創建和填充臨時表來處理它循環語句裏面是這樣的:爲什麼PL/SQL塊不創建臨時表?

DECLARE 
    cnt NUMBER; 
BEGIN 


    SELECT COUNT(tname) INTO cnt from tab where tname = 'MY_TEMP'; 
    IF (cnt > 0) THEN 
    EXECUTE IMMEDIATE 'DROP TABLE MY_TEMP'; 
    END IF; 

    EXECUTE IMMEDIATE 'CREATE GLOBAL TEMPORARY TABLE MY_TEMP (G NVARCHAR2(128), F NVARCHAR2(128), V NVARCHAR2(128)) ON COMMIT DELETE ROWS'; 

    INSERT INTO MY_TEMP VALUES (N'G-value1', N'F-value1', N'V-value1'); 
    INSERT INTO MY_TEMP VALUES (N'G-value2', N'F-value2', N'V-value2'); 
    ... 

    FOR record IN (SELECT G,F,V FROM MY_TEMP) 
    LOOP 

    ... Do something sophisticated with record.G, record.F, record.V 
    END LOOP; 

    COMMIT; 
END; 

當我運行PL-SQL Developer中這個腳本它告訴我該MY_TEMP表中的第一個INSERT或者即使我的EXECUTE IMMEDIATE'CREATE GLOBAL TEMPORARY TABLE ...'語句似乎沒有錯誤地執行,視圖也不存在。我在腳本執行後檢查了表內沒有MY_TEMP表

當我單獨運行EXECUTE IMMEDIATE'CREATE GLOBAL TEMPORARY TABLE ...'時,它運行正常,MY_TEMP表被真正創建。在此之後,整個腳本運行正常。

如何在不手動預先創建MY_TEMP表的情況下使用此腳本?

+0

你好,@DaveH。我已更正我的示例代碼。 – user149691

+2

這不是臨時表在Oracle中的工作方式。創建它們**一次**,然後在您的過程中使用它們 - 就像任何其他表一樣。 –

回答

4

如何使用這個腳本,而無需手動precreating MY_TEMP表?

你不行。除非您使用EXECUTE IMMEDIATE創建臨時表之後運行所有內容。但我不能一秒推薦這種方法。

的關鍵不在於你的腳本無法運行,但它未能編譯。如果Oracle不能首先編譯它,Oracle將不會開始運行您的塊。在Oracle試圖編譯你的PL/SQL塊的時候,這個表不存在。您有編譯錯誤,而不是運行時錯誤。

我懷疑你比較熟悉SQL Server中的臨時表,並試圖以同樣的方式在Oracle中使用臨時表。如果是這種情況,那麼您需要知道Oracle和SQL Server中的臨時表之間存在差異。首先,在Oracle中不存在作爲本地臨時表(即只有一個連接用戶可見的表)的東西。 Oracle確實有全局臨時表,但只有全局臨時表中的數據是臨時表。表格本身是永久性的,所以一旦它被創建,只有在你明確地刪除它時纔會被刪除。將其與SQL Server臨時表進行比較,一旦所有相關用戶斷開連接,這些臨時表將被刪除

我真的不認爲你需要在你的塊中創建臨時表。預先創建一次就足夠了。

0

爲什麼要放棄並創建臨時表?只需創建並使用它。

+0

我只是想確保在我嘗試創建它之前將其刪除。 – user149691

0

創建臨時表在Oracle中是不是最好的做法,改用PIVOT

0
The only way around for your problem is to make the whole INSERT INTO temp_table statements into EXECUTE IMMEDIATE in this way you can BYPASS the TABLE check during COMPILE Time first. 
But this way in my opinion is not good at all. There are some questions in my mind which has be answred before answering this question. 

1) Why Temp Table is created evertime and Dropped. 
We have option in GTT to keep or Remove Data after one Oracle Session. 
2) Is this script a one time job ? If Yes then we can go for once GTT creation and the rest script will work fine. 
0

的probloem不是wityh你的第一個插件。它是與你的塊的編譯。該表不存在,但是您正在引用它。嘗試創建它,所以它就在那裏,比如它會在完成之後。現在,代碼很可能會在您運行時對錶的引用進行編譯。

但是,如果您的代碼在表上存在共享鎖,那麼您將因放置而陷入困境,因此您不能放棄它。

您必須使您的選擇變爲動態,或確保表格已創建,並且在執行塊的過程中被刪除。