0

这可能是一个愚蠢的问题,但不知何故我无法绕过它。

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

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

当使用序列自动生成时,如何jobIdstatus表格中自动填充?jobIdlogs

更新

<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 但是我如何在休眠中做到这一点,知道吗?

就像是

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

想法?

4

2 回答 2

2

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

insert into logs (jobid) values (seq_jobid.nextval);
insert into status (jobid) values (seq_jobid.currval);
于 2012-07-03T14:56:43.373 回答
2

这取决于您如何使用序列来填充此列,但您很可能希望在填充表currval时使用序列jobIDstatus

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

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使用currval序列的。 currval为您提供会话的最新值,因此您不会看到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;
于 2012-07-03T14:57:53.637 回答