【问题标题】:pl/sql trigger alter sequencepl/sql 触发改变序列
【发布时间】:2018-08-07 20:27:35
【问题描述】:

我对 pl/sql 真的很陌生。我正在尝试做一个像这样的触发器(adr = 在删除行之后),但似乎我不能使用 ALTER SEQUENCE。这是删除一行后递减的正确方法还是应该使用过程?

CREATE OR REPLACE TRIGGER adr_trg
AFTER DELETE ON table
FOR EACH ROW
BEGIN
ALTER SEQUENCE table_seq INCREMENT BY -1;
END;

编辑:

我正在使用的序列:

CREATE SEQUENCE table_seq INCREMENT BY 1 START WITH 1;

我正在使用的触发器:

CREATE OR REPLACE TRIGGER bir_trg
   BEFORE INSERT ON table
   FOR EACH ROW
BEGIN
   IF :new.id IS NULL
   THEN
      :new.id := table_seq.nextval;
   END IF;
END bir_trg;

【问题讨论】:

  • 这看起来很奇怪。为什么要减少删除语句的序列?
  • 仅用于教育目的。

标签: oracle plsql triggers procedure


【解决方案1】:

首先,创建这个函数:

SQL> create or replace function fn_inc_by_minus_one( i_sch_name varchar2, i_seq_name varchar2 ) return number is   
   v_seq_no   number;
 begin
   execute immediate 'select '||i_sch_name||'.'||i_seq_name||'.nextval from dual' INTO v_seq_no;
   execute immediate 'alter sequence '||i_sch_name||'.'||i_seq_name||' increment by -2 minvalue 0';
   execute immediate 'select '||i_sch_name||'.'||i_seq_name||'.nextval from dual' INTO v_seq_no;
   execute immediate 'alter sequence '||i_sch_name||'.'||i_seq_name||' increment by 1 minvalue 0';
   return v_seq_no;
  end;
  /

当您需要将序列增加-1 时,只需运行此语句(不会破坏序列的原始递增机制 select jsao_super_cities_seq.nextval from dual;+1 递增):

 SQL> var n number;
 SQL> exec :n:=fn_inc_by_minus_one('myschema','jsao_super_cities_seq');
 /  

【讨论】:

  • 这没有按预期工作。实际上,由于一些错误,我不得不放弃我的序列并创建一个新序列。
  • @Sebastián 对不起,我完全改变了逻辑,现在它给出了真实的结果。
【解决方案2】:

我可能在这里“阅读字里行间”,但我怀疑您的目标是,如果您在由 sequence.nextval 填充的表中有 5 个条目,例如

ID
---
1
2
3
4
5

然后有人删除了第 5 行,您想将序列恢复到值 4。

这有两个问题:

  1. 如果有人删除“3”怎么办?您不能将序列回滚 2,因为当您使用 seq=3 并移动到 seq=4 时,您会遇到冲突

  2. 您不能保证序列没有间隙。只需某人获取一个序列值,然后发出回滚(或在事务中遇到任何其他类型的错误,该序列值就永远消失了)

这让我想到了最重要的问题:

你为什么还要担心差距?

【讨论】:

  • 好的,谢谢,我没有想到那些场景。我不会担心差距:)
【解决方案3】:

您不能在触发器中使用 Alter 语句。根据定义,触发器不能直接使用提交或回滚,并且“Alter”语句具有自动提交。如果您希望在触发器中使用提交或回滚,您可以为此目的使用“自治事务”块。

另外,您不需要使用触发器将序列 nextval 插入列中,您可以直接在插入语句中使用 seq_name.next_val。减少序列的值会导致数据不一致,例如,您在表中插入了 10 行,序列的当前值为 11。假设现在删除了 id=2 的行,您将序列值减少到 10。在新插入时如果 id 列是 PK 则要么抛出错误,否则创建两行 id = 10。

【讨论】:

猜你喜欢
  • 2013-07-07
  • 1970-01-01
  • 2011-08-06
  • 2010-10-21
  • 1970-01-01
  • 2012-04-20
  • 2014-04-07
  • 2018-04-01
  • 2017-09-14
相关资源
最近更新 更多