2016-12-08 47 views
0

標題可能有點混亂 - 我會在內心深處到這裏的細節...如何執行非唯一鍵的唯一性在Oracle表中每個任務

想象簡化日誌表:

run_id | step_id | result | 
-------------------------------- 
    1 |  1  | done | 
    1 |  2  | done | 
    1 |  3  | done | 
    1 |  4  | done | 
    2 |  1  | failed | 
    3 |  1  | done | 
    3 |  2  | done | 

但是當我在同一時間運行兩個作業(使用run_id 1和2)時,發生它們共享run_id,這是不正確的!

我想每個職業有不同的ID。顯然:)

如何執行在Oracle(PL/SQL - 主要是包)開始在同樣的時間(即上午6時)工作..

你有什麼想法嗎?你如何解決這種情況?如果我通過創建唯一索引(run_id,step_id)怎麼辦? 「第二」工作會失敗嗎?或者它會自動增加值?

SELECT nvl(max(run_id), 0)+1 INTO v_run_id 
FROM my_schema.log_table; 

這是代碼,獲取新的價值......但正如上面

THX

編輯這是行不通的,因爲...: 作爲一種變通方法我想關於使用字符串和日期......使用起始日期和常量字符串(run_name而不是run_id)......這樣的表格可以像

run_name |  run_date   | step_id | result | 
-------------------------------------------------------- 
my_job#1 | 1/1/2016 7:00:00 AM | 1  | done | 
my_job#1 | 1/1/2016 7:00:00 AM | 2  | done | 
my_job#1 | 1/1/2016 7:00:00 AM | 3  | done | 
my_job#1 | 1/1/2016 7:00:00 AM | 4  | done | 
my_job#2 | 1/1/2016 7:00:00 AM | 1  | failed | 
my_job#1 | 1/2/2016 7:00:00 AM | 1  | done | 
my_job#1 | 1/2/2016 7:00:00 AM | 2  | done | 

這可能工作..我只是CUR不知道如何使用ID

回答

1

您獲得run_id這樣目前:

SELECT nvl(max(run_id), 0)+1 INTO v_run_id 
FROM my_schema.log_table; 

我假設你的代碼使用run_id插入每個步驟時。您應該創建一個順序是這樣的:

CREATE SEQUENCE run_id_seq; 

然後用替換你上面的查詢:

SELECT run_id_seq.nextval FROM dual; 

如果你已經在你的表中現有的數據,你可能會創建時需要START WITH值的確保它不會發生衝突。

+0

恰恰:)很棒......回答!非常感謝你 –

0

處理此問題的更好方法是使用序列。在Oracle 12c中,可以使用generated always構造自動爲列分配一個連續值(如其他數據庫中的identity,serialauto_increment)。

在舊版本中,您使用觸發器來維護它。在定義表格和序列中的列後,觸發器代碼如下所示:

create trigger t_trigger 
before insert on t 
for each row 
begin 
    select seq.nextval into new.id 
    from dual; 
end; 

使用這樣的構造,值永遠不會相同。

+0

但這意味着我會得到不同的每個插入正確的run_id?我將無法通過run_id –

+0

@ Mr.P確定您會發現相同的「運行」。所以在你的情況下,你需要直接從序列中獲取值,而不是爲插入的每一行使用觸發器。 –

相關問題