Oracle:如果父表引用列具有值,则自动填充外键

时间:2012-07-03 14:41:52

标签: sql oracle hibernate foreign-keys

这可能是一个愚蠢的问题,但不知怎的,我无法解决它。

我有表statuslogs,两个表都有jobId列。 jobId是基于序列生成的,因此我想将sequence generated jobIdlogs表添加到status页面。

我在引用status列到jobId表的logs表中创建了外键,但是status表中没有填充jobId值。

如果使用序列在jobId中自动生成status,我如何在jobId表格中自动填充logs

更新

<id name="jobid"
        column="JOBID"
        type="long"
        unsaved-value="-1">
      <generator class="native">
            <param name="sequence">ID_SEQ</param>
        </generator>
    </id>

以下是如何为status页面生成id,如我所知需要使用ID_SEQ.curval,但我怎么能在hibernate中做到这一点,任何想法?

类似

<id name="id"
        column="ID"
        type="long"
        unsaved-value="-1">
      <generator class="native">
            <param name="sequence">ID_SEQ.curval</param>
        </generator>
    </id>

思想?

2 个答案:

答案 0 :(得分:2)

在日志表中插入行后,只需使用currval

insert into logs (jobid) values (seq_jobid.nextval);
insert into status (jobid) values (seq_jobid.currval);

答案 1 :(得分:2)

这取决于您使用序列填充此列的方式,但在填充currval表中的jobID时,您很可能希望使用序列的status

在最简单的情况下,您有两个表和一个序列

SQL> create table logs(
  2    jobID number primary key
  3  );

Table created.

SQL> create table status (
  2    jobID number references logs(jobID)
  3  );

Table created.

SQL> create sequence jobID_seq;

Sequence created.

当您插入logs时,您使用序列的nextval,当您插入status时,您使用序列的currvalcurrval为您提供了会话的最新价值,因此您不会看到为其他会话提供currval的风险

SQL> insert into logs values( jobID_seq.nextval );

1 row created.

SQL> insert into status values( jobID_seq.currval );

1 row created.

SQL> select * from logs;

     JOBID
----------
         5

SQL> select * from status;

     JOBID
----------
         5

如果您正在使用触发器(我在这里使用的是11g语法 - 如果您使用的是旧版本,则可以使用旧的SELECT jobID_seq.nextval into :new.jobID from dual语法)

SQL> create trigger trg_logs
  2    before insert on logs
  3    for each row
  4  begin
  5    :new.jobID := jobID_seq.nextval;
  6  end;
  7  /

Trigger created.

SQL> create trigger trg_status
  2    before insert on status
  3    for each row
  4  begin
  5    :new.jobID := jobID_seq.currval;
  6  end;
  7  /

Trigger created.
但是,我不太确定尝试自动填充这样的外键真的很有意义。据推测,例如,在某些情况下,您将向子表中添加行,而不是仅插入父行。也许您可以通过向IF表上的触发器添加status条件来解决这个问题,该表检查是否已经提供了非NULL值

create trigger trg_status
  before insert on status
  for each row
begin
  if( :new.jobID IS NULL )
  then
    :new.jobID := jobID_seq.currval;
  end if;
end;