2010-06-28 19 views
1

我有一個包將插入一個表中的單個父記錄,並在parent_id上具有FK的另一個表中的相關子記錄。這些函數中的每一個都將由外部程序調用,並且所有插入子項的調用都可能不包含在同一事務中。當我在PL/SQL中插入子記錄時,應該如何保持指向父記錄的指針?

我想知道是否有任何方法可以避免手動跟蹤parent_id並將它傳遞到每個過程的參數列表中。我已經考慮過使用sys_context,但不認爲這將工作,因爲它不會在一個單一的事務。

是否有任何其他策略,或者我只需要吸取它並將parent_id傳遞給每個方法?

回答

3

你可以只使用一個包變量是這樣的:只要你的數據庫連接存在

package body mypackage is 

    g_parent_id integer; 

    procedure insert_parent (...) 
    is 
    begin 
     insert into parent (...) values (...) 
     returning id into g_parent_id; 
    end; 

    procedure insert_child (...) 
    is 
    begin 
     insert into child (parent_id, ...) values (g_parent_id, ...); 
    end; 
end; 

包變量仍然存在。這在無狀態環境(如Web應用程序)中不起作用。

這就是說,我會贊成保持程序模塊化,每次都通過ID。這樣沒有任何意外的事情會發生

+0

我以前沒有使用過包變量,但是從我讀過的內容中可以看出,它們會持續一段時間。通過一個會話將值設置爲一個包變量的值是否對任何其他會話可見,或者它們是否完全隔離?基本上,每個會話都會有這個變量的副本來完成它所希望的事情,或者一個會話是否可以爲另一個會話更改此變量的值? – 2010-06-28 15:08:03

+0

每個會話都有自己的副本,他們不能看到對方。因此,只要在整個交易過程中維持一個會話,即在「有狀態」環境中,這種方式就可以正常工作。 – 2010-06-28 15:12:14

1

關鍵問題是您的調用應用程序中的會話是否合併或「粘滯」。

如果相同的連接/會話被外部程序重新用於每個事務,那麼將parentId存儲在包變量中將會很好。

如果你有連接池,那麼使用包變量開始變得棘手/積極危險。

如果插入子項的調用位於不同的事務中,並且您有連接池,則可以看出您無法避免告訴第二個事務需要parentId。注意事項:如果您更關心的是簡化包的性能而不是性能,並且您有這方面的內容。 。 。

對於外部應用程序中的每個數據庫調用,將唯一標識調用進程的東西設置爲SYS_CONTEXT或包變量(我們有類似的東西,這樣我們就可以派生調用方法和'真實'而不是混合d/b用戶)。

根據此唯一標識符和時間在父表上創建輔助鍵/索引。

創建一個函數來檢索當前會話的最新ParentId(假定唯一標識符將被正確設置)。

在您插入的孩子中使用此功能。

相關問題