2014-10-29 70 views
2

在Oracle數據庫上,如何執行下面的邏輯(即「等到至少有一行返回並返回列值」),但沒有輪詢(循環,浪費CPU和可能的I/O),但是有一些等待/阻止機制? 因此,當調用get_one()函數時,它不應該返回,直到它可以從匹配一些條件的表中獲取一行爲止。如何等待查詢返回行?

function get_one() 
return number 
is 
c1 sys_refcursor; 
n number; 
begin 
    loop 
     open c1 for select number_column from t1 where some_conditions; 
     fetch c1 into n; 
     if not c1%notfound then return n; 
     close c1; 
     dbms_lock.sleep(1); -- this wait reduces load, but is still polling, also it delays reaction time 
    end loop; 
end; 

的解決方案應爲外部應用程序的工作(比如與J2EE,.NET和類似應用服務器),所以使用觸發器可能會不適合。

+0

也許你可以利用這個函數使用的資源,通過調用方法呢?他們會一直等待這些信息,我不確定從資源的角度來看它是怎麼樣的。 – Sebas 2014-10-29 17:39:06

+0

等待一個事件是一個相當普遍的編程模式,調用者會沒事的。 – 2014-10-30 09:24:15

回答

0
function get_one() 
return number 
is 
n number; 
begin 
    loop 
     select (select number_column from t1 where some_conditions) into n from dual; 
     if n is null then 
      dbms_lock.sleep(1); -- wait 1 second 
     else 
      return n; 
     end if; 
    end loop; 
end; 

DBMS_LOCK包提供給Oracle鎖管理 服務的接口。您可以請求鎖定特定模式,爲其指定一個可在另一個過程中識別的同名或另一個 名稱的獨特名稱,更改鎖定模式並釋放它。

你可能需要一些贈款,以執行該Oracle包

+1

這仍然是輪詢,只是在民意測驗之間有一段延遲。 – 2014-10-29 17:41:56

+0

@DavidBalažic但是在這種情況下CPU並沒有如此巨大的消耗。你也可以看看DBMS_SCHEDULER包。它可能會幫助 – Multisync 2014-10-29 17:45:48

0

我不贊成實現一個不斷直接在Oracle等待或輪詢代碼。這可能會歪曲像DB Time和等待時間這樣的Oracle統計數據。

爲了實現這都需要通過特定的行集合行爲正在創建或修改你可以求助於服務器代碼:

  1. ,在預定的時間間隔和查詢中醒來的日程工作行。如果行存在,那麼它會調用對新行進行操作的過程。

  2. 觸發器 根據插入的內容,可以在創建行時調用觸發器。當您嘗試修改具有觸發器的原始行時,請小心可能出現的突變對象錯誤。

如果它是所謂的「get_one」客戶端應用程序,你可能也有客戶端應用程序輪詢它基於定時器每隔幾秒鐘(無客戶端或DB CPU浪費在調用之間)。

+0

[DBMS_AQ.LISTEN](http://docs.oracle.com/cd/E11882_01/appdev.112/e40758/d_aq.htm#ARPLS099)是一個等待數據庫的標準過程,因此等待數據庫不應該是一個問題。 – 2017-04-04 13:45:57