2016-12-08 49 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确定您会发现相同的“运行”。所以在你的情况下,你需要直接从序列中获取值,而不是为插入的每一行使用触发器。 –

相关问题