重置自动递增序列 pl-sql

Posted

技术标签:

【中文标题】重置自动递增序列 pl-sql【英文标题】:Reset auto increment sequence pl-sql 【发布时间】:2011-11-21 03:54:45 【问题描述】:

如何重置自增主键?

我有一个像这样的 doc_id_seq 和一个 doc_pk_trg 触发器:

CREATE SEQUENCE doc_id_seq START WITH 1;

CREATE OR REPLACE TRIGGER doc_pk_trg
BEFORE INSERT ON TFIDF FOR EACH ROW
BEGIN  
 IF :NEW.doc_id IS NULL THEN    
   SELECT doc_id_seq.NEXTVAL INTO :NEW.doc_id FROM DUAL;  
     END IF;
     END;
 /

我想学习重置序列。我怎样才能做到这一点 ?

【问题讨论】:

您要解决的问题是什么?正如 Ollie 指出的那样,您可以使用 ALTER SEQUENCE 重置序列。但是你应该很少关心主键的值。唯一让我大吃一惊的是,如果你正在做一些事情,比如手动将数据从一个环境复制到另一个环境(即 prod 到 dev),并且你需要增加 dev 中序列的NEXTVAL,这样你就不会生成重复键。然而,当这个问题被问到时,人们通常会试图避免序列生成值中的“空白”,这将不起作用。 【参考方案1】:

您可以使用 ALTER SEQUENCE 语法。

Tom Kyte 在这里解释了如何做到这一点:

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1119633817597

【讨论】:

【参考方案2】:

只需放下然后重新创建序列。

【讨论】:

如果是表的pk,在创建序列查询时别忘了加上START WITH "max_pk+1"【参考方案3】:

这就是我要重置它的方式

CREATE OR REPLACE PROCEDURE reset_sequence (
   p_sequence_name   IN   VARCHAR2,
   p_new_value       IN   NUMBER
)
AS
   l_current_value     NUMBER;
   v_sequence_exists   NUMBER;
BEGIN
   SELECT 1
   INTO   v_sequence_exists
   FROM   user_sequences
   WHERE  sequence_name = p_sequence_name;

   EXECUTE IMMEDIATE 'SELECT ' || p_sequence_name || '.nextval FROM dual'
   INTO              l_current_value;

   /*Not possible to increment by 0 !*/
   IF (p_new_value - l_current_value - 1) != 0
   THEN
      EXECUTE IMMEDIATE    'ALTER SEQUENCE '
                        || p_sequence_name
                        || ' INCREMENT BY '
                        || (p_new_value - l_current_value - 1)
                        || ' MINVALUE 0';
   END IF;

   EXECUTE IMMEDIATE 'SELECT ' || p_sequence_name || '.nextval FROM dual'
   INTO              l_current_value;

   EXECUTE IMMEDIATE 'ALTER SEQUENCE ' || p_sequence_name || ' INCREMENT BY 1 ';
EXCEPTION
   WHEN NO_DATA_FOUND
   THEN
      raise_application_error (-20001, 'Sequence does not exist');
END;

与删除和重新创建相比,这具有额外的好处,即不会使任何相关架构对象失效。

【讨论】:

如果您不希望将其全部放入存储过程中,我会添加一些错误检查以确保在尝试重置序列之前存在序列等,并且因为它正在执行动态 SQL我可能也会添加一些 SQL 注入保护,以防万一...... 我同意,但有些人是新手搜索这些答案,你永远不知道他们会做什么......我相信你已经看到了足够多的类似事情发生的案例。跨度> 好的,已更改程序以验证序列。将使注射成为不可能。

以上是关于重置自动递增序列 pl-sql的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 自动递增和选择计数

重置自动递增编号

如何生成每年重置的自动递增 ID 号

ORACLE 10g 自动递增触发器/序列不按编程递增

解释使用 Hibernate 映射自动递增复合 id 序列的行为

postgreSQL怎样创建一个序列号/自动递增的字段