2010-09-22 74 views
4

如何在向表中插入一些行後獲得與「提交」觸發器等效的內容?Oracle:模擬「提交後」觸發器

在向表中插入多行後,我想向外部進程發送一條消息,指出可以處理的行。使用語句級觸發器會導致每個插入一條消息,並且我只想發送一條消息,指出「有要處理的行」。

+1

你爲什麼不使用隊列?請參閱:http://download.oracle.com/docs/cd/B10500_01/appdev.920/a96587/qintro.htm –

+0

找到我們隊列中的3個問題:(1)需要的應用程序鏈接到Oracle運行時,(2)等待時間超過我們喜歡的時間,(3)不能很好地擴展到計算農場的規模。 –

+0

似乎隊列不能解決基本問題......合併多個插入,以便只生成一條消息。 –

回答

3

,因爲你需要觸發外部過程,看看DBMS_ALERT而不是DBMS_JOB。

外部進程將通過調用存儲過程來主動偵聽警報。存儲過程將在警報發出並提交後立即返回。

請注意,DBMS_ALERT是一個序列化設備。因此,表示相同警報名稱的多個會話會阻塞,就像它們更新表中的同一行一樣。

+2

這是正確的答案,因爲它允許合併多個插入。從Oracle Doc中:「警報可以比相應的應用程序等待調用更頻繁地發送信號,在這種情況下,舊警報將被丟棄,應用程序始終會獲得最新警報(基於事務提交時間)。 –

7

創建一個工作。在提交之前它不會實際提交。 (注:DBMS_SCHEDULER通常比DBMS_JOB更好,但在這種情況下,你需要使用老DBMS_JOB包)。

declare 
    jobnumber number; 
begin 
    dbms_job.submit(job => jobnumber, what => 'insert into test values(''there are rows to process'');'); 
    --do some work here... 
    commit; 
end; 
/
+0

+1:簡單,高效。 –

+0

有沒有一種方法可以使用它來合併插入?我想處理多個插入,然後執行一個「準備就緒」的步驟。 –

+0

工作如何進行?在您控制的單個事務中(通過存儲過程還是某個事物),還是僅由用戶使用簡單的插入語句?表級AFTER觸發器是否工作? –

1

你可以設置一個標誌,說:「我已經發送的消息」。 要確保你「復位」上提交的標誌,使用dbms_transaction.local_transaction_id那麼你可以簡單地做一個

IF v_flag IS NULL OR dbms_transaction.local_transaction_id != v_flag THEN 
    v_flag := dbms_transaction.local_transaction_id; 
    generate message 
END IF;