2017-03-16 28 views
0

我使用下面的触发器在我的测试表中插入:更新ID,如果序列MAX_VALUE达到

create or replace 
TRIGGER TRG_CYCLE 
BEFORE INSERT ON TEST_CYCLE 
FOR EACH ROW 
BEGIN 
IF :NEW.LOGID IS NULL 
    THEN SELECT SEQ_CYCLE.nextval INTO :NEW.LOGID from dual; 
END IF; 
END; 

SEQ_CYCLE是序列。现在,我必须使用CYCLE选项才能在达到MAX_VALUE之后以1开头。由于我不想重复LOGID,如果LOGID存在,我想要执行UPDATE,如果不是INSERT。我可以在触发器内执行此操作吗?

+0

所以你的要求是覆盖表中的随机行?迷人。 – APC

+0

你问是否可以,问题是你是否应该这样做,答案是否定的。只需在序列上提供高数量限制,您就不必担心重复。另外,对于12C,您可以指定一个序列作为列的默认值。 – unleashed

回答

0

如果我理解的很好,您可能需要一个INSTEAD OF触发器;建立这样一个触发器,你需要在你的表上创建一个VIEW并在这个视图上构建触发器。

例如,假设您有:

create sequence SEQ_CYCLE maxValue 3 cycle nocache; 
create table TEST_CYCLE (logId number, someColumn varchar2(20)); 

您可以创建一个视图,在视图中的触发器:

create or replace view v_test_cycle as select * from test_cycle; 

create or replace trigger trgCycle 
instead of insert on v_test_cycle 
for each row 
declare 
    vCheck number; 
    vSeqVal number := SEQ_CYCLE.nextVal; 
begin 
    select count(*) 
    into vCheck 
    from v_test_cycle 
    where logId = vSeqVal; 
    -- 
    if vCheck = 0 then 
     insert into test_cycle(logId, someColumn) values (vSeqVal, :NEW.someColumn); 
    else 
     update test_cycle 
     set someColumn = :NEW.someColumn 
     where logId = vSeqVal; 
    end if; 
end; 

如果你在视图上插入,这就是你得到:

SQL> select * from test_cycle; 

no rows selected 

SQL> insert into v_test_cycle(someColumn) values('some value 1'); 

1 row created. 

SQL> insert into v_test_cycle(someColumn) values('some value 2'); 

1 row created. 

SQL> insert into v_test_cycle(someColumn) values('some value 3'); 

1 row created. 

SQL> insert into v_test_cycle(someColumn) values('some value 4'); 

1 row created. 

SQL> insert into v_test_cycle(someColumn) values('some value 5'); 

1 row created. 

SQL> select * from test_cycle; 

    LOGID SOMECOLUMN 
---------- -------------------- 
     1 some value 4 
     2 some value 5 
     3 some value 3 

SQL>