2010-06-14 25 views
2

我正在將GTT轉換爲oracle類型,正如APC出色的answer中所解釋的那樣。但是,某些GTT正在根據另一個表中的選擇查詢進行更新。例如:oracle的類型可以像表一樣更新嗎?

UPDATE my_gtt_1 c 
    SET (street, city, STATE, zip) = (SELECT src.unit_address, 
              src.unit_city, 
              src.unit_state, 
              src.unit_zip_code 
             FROM (SELECT mbr.ROWID row_id, 
                unit_address, 
                RTRIM(a.unit_city) unit_city, 
                RTRIM(a.unit_state) unit_state, 
                RTRIM(a.unit_zip_code) unit_zip_code 
               FROM table_1  b, 
                table_2   a, 
                my_gtt_1 mbr 
               WHERE type = 'ABC' 
               AND id = b.ssn_head 
               AND a.h_id = b.h_id 
               AND row_id >= v_start_row 
               AND row_id <= v_end_row) src 
             WHERE c.ROWID = src.row_id) 
WHERE state IS NULL 
    OR state = ' '; 

如果my_gtt_1不是全局臨時表,但一個Oracle集合類型則是有可能這樣做更新此複雜嗎?或者在這些情況下,我們最好使用全局臨時表?

回答

1

您無法對對象類型執行設置UPDATE操作。你將不得不做逐行,如:

FOR i IN l_tab.FIRST..l_tab.LAST LOOP 
    SELECT src.unit_address, 
      src.unit_city, 
      src.unit_state, 
      src.unit_zip_code 
    INTO l_tab(i).street, 
      l_tab(i).city, 
      l_tab(i).STATE, 
      l_tab(i).zip 
    FROM (your_query) src; 
END LOOP; 

因此,應該嘗試做所有的計算在創建時(在那裏你可以BULK COLLECT)。顯然,如果你的進程需要很多步驟,你可能會發現全局臨時表優於內存結構。


從你最近提出的問題來看,你似乎試圖用對象表替換所有的全局臨時表。我建議小心,因爲一般來說,它們是不可互換的:

  • 對象表是內存中的結構:您不想將百萬行表加載到內存中。它們主要用作緩衝區:將幾行(例如100行)加載到結構中,執行您需要對這些行執行的操作,然後加載下一批。您不能輕易將此結構視爲常規表格:例如,您只能使用標準索引鍵高效搜索此結構(除非您定義要由rowid索引的結構,否則無法在示例中通過rowid進行搜索)。
  • 另一方面,臨時表格與普通表格非常相似。您可以在其中加載數百萬行,執行連接,複雜的集合操作。您可以索引臨時表以進一步優化。

在我看來,你試圖進行的改變將會對你的邏輯進行大規模的改革,並且它可能不會更好。一般來說,你不會用對象表來替換GTT。您可以通過直接使用SET操作(在您的數據上直接使用大量UPDATE/DELETE/INSERT而不使用臨時表),以顯着提高性能來移除GTT。

我建議選擇一個解決方案之前執行基準(這可能是你在做什麼,現在:)

1

我認爲APC的answer to your previous question的這一部分是與此有關:

全局臨時表都還不錯 如果我們有很多中間 處理這實在是太 複雜,用一個單一的 來解決SQL查詢。特別是如果必須將處理應用於檢索行的子集 。

你不能用UPDATE語句更新內存數據,就像你可以使用GTT一樣;您需要編寫過程代碼來查找和更改有問題的數組元素。

+0

+1引用我:) – APC 2010-06-15 12:06:07

+0

不能使用UPDATE(前11至少),但如果你有一個更好的用SQL表達的操作,你可以編寫一個接收集合的函數,使用SELECT over TABLE(myCol),BULK COLLECT將其轉換爲相同類型的resultCol,然後執行類似於myCol的操作:= lTransform(myCol )。 – JulesLt 2010-07-15 14:38:48

相關問題