IT瑞先生 2015-11-03 07:29 采纳率: 0%
浏览 616

求大神解惑,oracle使用触发器报错,

求大神解惑,oracle使用触发器,在插入的表中无数据时,报错(如下图),再执行就成功了,可是序列从2开始了,我想问下如何让它从1开始不报错
下面是触发器:
create or REPLACE trigger trigger_name
BEFORE insert on test
for each row
DECLARE
v_newVal NUMBER(12) := 0;
BEGIN
if(INSERTING AND :new.DEVICEBRAND_SK IS NULL) then
select sequence_p .nextval into v_newVal from DUAL;

 if v_newVal = 1 THEN
   SELECT NVL(max(devicebrand_sk),0) INTO v_newVal FROM test;
   v_newVal := v_newVal + 1;
   end IF ;
 :new.devicebrand_sk := v_newVal;

end if;
end;
下面是序列:
create sequence sequence_p minvalue 1 maxvalue 999999999999999999999999 start with 1 increment by 1 cache 20;

图片说明

  • 写回答

1条回答 默认 最新

  • 你知我知皆知 2024-08-04 16:14
    关注

    以下回答参考 皆我百晓生券券喵儿 等免费微信小程序相关内容作答,并由本人整理回复。

    Oracle触发器和序列之间的冲突可能由于触发器对序列值的操作导致。为了使序列从1开始,你可以尝试以下方法:

    1. 将触发器修改为直接更新devicebrand_sk列而不是通过序列。例如:
    CREATE OR REPLACE TRIGGER trigger_name
    BEFORE INSERT ON test FOR EACH ROW
    DECLARE
    BEGIN
        UPDATE test SET devicebrand_sk = CASE WHEN INSERTING THEN nextval('sequence_p') ELSE devicebrand_sk END;
    END;
    

    这将避免通过序列操作更新devicebrand_sk

    1. 如果你必须通过序列进行更新,请确保在触发器内处理序列的nextval()调用。例如:
    CREATE OR REPLACE TRIGGER trigger_name
    BEFORE INSERT ON test FOR EACH ROW
    DECLARE
        v_newVal NUMBER(12) := 0;
    BEGIN
        IF INSERTING AND :new.DEVICEBRAND_SK IS NULL THEN
            v_newVal := sequence_p.nextval;
        ELSE
            v_newVal := :new.DEVICEBRAND_SK;
        END IF;
        
        UPDATE test SET devicebrand_sk = v_newVal WHERE devicebrand_sk <> :new.DEVICEBRAND_SK;
        
        :new.DEVICEBRAND_SK := v_newVal;
    END;
    
    1. 在触发器内部添加检查以确保v_newVal始终等于1或序列中的下一个可用值。例如:
    CREATE OR REPLACE TRIGGER trigger_name
    BEFORE INSERT ON test FOR EACH ROW
    DECLARE
        v_newVal NUMBER(12) := 0;
    BEGIN
        IF INSERTING AND :new.DEVICEBRAND_SK IS NULL THEN
            v_newVal := sequence_p.nextval;
        ELSE
            v_newVal := :new.DEVICEBRAND_SK;
        END IF;
        
        IF v_newVal = 1 THEN
            INSERT INTO test VALUES (v_newVal);
        END IF;
        
        :new.DEVICEBRAND_SK := v_newVal;
    END;
    

    请注意,这些更改可能会改变触发器的行为,因此在实施之前,请确保测试环境可以正确运行这些变更。

    评论

报告相同问题?