`

实现在删除数据后,自增列的值连续

阅读更多

无意间放入发现,觉得很有用,先记录下来

 

实现在删除数据后,自增列的值连续其处理思路如下:

在删除自增列所在表的记录时,将删除行的自增列的值保存在另外一个表,以便下次新增数据时,使用原来被删除的自增列的值。

实现步骤:

创建两个表test_id(自增列所在表),test_r(记录被删除的自增列其值)

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[test_id]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[test_id]
GO

CREATE TABLE [dbo].[test_id] (
 [id] [int] IDENTITY (1, 1) NOT NULL ,
 [name] [varchar] (20) COLLATE Chinese_PRC_CI_AS NULL
) ON [PRIMARY]
GO

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[test_r]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[test_r]
GO

CREATE TABLE [dbo].[test_r] (
 [r_id] [int] NULL
) ON [PRIMARY]
GO

 在删除test_id 的记录时,将起响应id保存到test_r表,通过test_id 表的delete触发器实现

CREATE TRIGGER dt_test_id ON [dbo].[test_id]
FOR  DELETE
AS
begin
 declare @row int
 set @row=0
 if exists(select * from deleted )
  begin
   insert into test_r(r_id) select id from deleted
  end
 
end

 向表test_id插入数据时,判断其id是否存在与test_r表中,如存在则删除id在test_r值,通过test_id的插入触发器实现:

CREATE TRIGGER it_test_id ON [dbo].[test_id]
FOR INSERT
AS
begin
 if @@rowcount=0 return
 declare @row int
 set @row=0
 if exists(select * from inserted )
  begin
   delete from test_r where  exists(select id from inserted where  test_r.r_id=inserted.id )
  end
 
 end
 

在插入前需判断test_r表是否存在被删除的id ,若存在,则使用其test_r表中的记录作为插入行id栏位的值

如没有,则直接插入。通过test_id表的插入前触发器实现:

 

 
CREATE trigger iit_test_id on test_id
instead of insert
as
begin
declare @min_id int
declare @id int
declare @rowcount int
declare @rowcount_i int
declare @name varchar(20)
declare @sql varchar(8000)
create table #t(id int identity(1,1) ,name varchar(20) null,tag varchar(1) null)
insert into #t(name,tag) select name,'0' from inserted
--如果存在断号,取已经存在的断号。
if exists(select  * from test_r)
  begin
   -- 可以显示插入自增列。
   SET IDENTITY_INSERT test_id on
   --获取可用断号记录
   select @rowcount=count(*) from test_r
   --获取插入行的记录。
   select @rowcount_i=count(*) from inserted
   --当断号记录的数量大于插入数据的行数时,则所有的插入记录的 id均使用断号,故返回inserted 表中的所有行
   --当断号记录的数量小于插入数据的行数时,则所有的插入记录前的(断号记录总行数)行id均使用断号,故返回inserted 表中前(断号记录总行数)的行
   if @rowcount > @rowcount_i
    set @rowcount=@rowcount_i
   
   set @sql=''
   set @sql='declare cur_get cursor     for select top '+cast(@rowcount as varchar(20))+'  id,name from #t order by id '
    
   exec(@sql)
   open cur_get
   fetch cur_get into @id, @name
   while @@fetch_status=0
    begin
        
              select @min_id =min(r_id) from test_r
     if exists(  select min(r_id) from test_r)
      begin
              update #t set tag='1' where id=@id
      end
              insert into test_id(id,name)values(@min_id,@name)
     
              fetch cur_get into @id,@name
    end
   close cur_get
   deallocate cur_Get
   
   SET IDENTITY_INSERT test_id off

   --当断号记录的数量小于插入数据的行数时,使用断号记录的剩余行则不需要显示id插入
   if exists(select * from #t where tag='0')
    begin
     insert into test_id(name) select name from #t where  tag='0'
    end
   drop table #t
  end
 else
  -- 不存在断号就直接插入。
  insert into test_id(name )select name from inserted

 
end
 

 

 

 

 

 

 

 

 

分享到:
评论
1 楼 yulanlian 2012-07-11  

相关推荐

    主键自增功能测试报告1

    5. **部分数据删除后的计数起点**:当删除部分数据后,自增计数器应保持连续,不因删除操作而改变起点。 6. **指定计数起点和自增步长**:检验是否可以设置自增起始值和每次递增的步长,并按设定规则运行。 7. **...

    自增主键为什么不是连续的?.pdf

    在MySQL 5.7及以前版本,重启实例可能导致自增值重置为当前数据中的最大ID值加1,这可能导致自增主键的不连续。 自增值的修改机制涉及两种情况:一是插入数据时未指定id值,此时会使用当前的自增值填充;二是插入时...

    oracle通过触发器,实现序列自增

    本文将详细介绍如何通过触发器与序列相结合的方式,在Oracle数据库中实现记录的自增功能。 #### 一、理解Oracle序列 在开始之前,首先需要了解Oracle中的序列。序列是一个数据库对象,它能够生成连续的整数序列。...

    创建oracle数据库中表的主键和自增

    为了实现主键的自增,我们可以创建一个触发器,在插入新记录之前为该记录分配序列的下一个值。 **创建触发器的基本语法:** ```sql CREATE OR REPLACE TRIGGER BEFORE INSERT ON FOR EACH ROW BEGIN SELECT ...

    SQL Server中实现字段值自动增长且连续.pdf

    通过在触发器中使用游标,可以遍历相关数据记录,并对不连续的字段值进行调整,使字段值在删除记录后仍保持连续。使用游标的缺点是相对低效,特别是在数据量大的情况下,执行速度较慢。 综上所述,SQL Server中实现...

    PHP中ID设置自增后不连续的原因分析及解决办法

    为了解决这个问题,需要在删除ID列后再添加一个语句来设置自增值: ```sql ALTER TABLE tablename AUTO_INCREMENT = 1; ``` 这样,即使有记录被删除,新插入的记录ID也会从1开始。 另一个可能导致自增ID不连续的...

    sql2005自增字段归零.docx

    在SQL Server 2005中,自增字段(Identity字段)是一种特殊类型的列,它在每次插入新记录时自动递增其值,通常用于创建唯一的主键。然而,在某些情况下,用户可能需要重置这个自增字段,使其从特定值(如1)重新开始...

    oracle自增序列

    - **保证唯一性**:在需要确保某列值唯一的情况下,使用序列可以轻松实现这一点。 - **批量数据处理**:在处理大量数据时,序列可以帮助快速生成一系列唯一的标识符。 总之,Oracle自增序列是一种非常实用的功能,...

    自增字段的SQL语句解决方案

    在数据库设计与管理中,自增字段是一个非常实用的功能,它能够自动为每一条新记录分配一个唯一的、连续的整数值。这对于需要唯一标识符(例如主键)的场景特别有用。本文将详细介绍自增字段在SQL中的实现方法及相关...

    oracle里建一个自增字段示例

    在Oracle数据库中,自增字段通常通过序列(Sequence)和触发器(Trigger)来实现。本篇文章将详细解释如何创建一个自增字段,并通过具体的步骤和代码示例来进行说明。 #### 序列(Sequence) 序列是一种数据库对象...

    SQL Server 之 SET IDENTITY_INSERT

    这在需要控制数据插入顺序或需要在标识列中插入非连续值时非常有用。例如,如果需要在表中插入一条记录,并且希望这条记录的标识列值为某个特定值而非自动递增的下一个值,则可以使用此命令。 #### 如何使用 SET ...

    编号自动增长

    在对数据库进行任何操作之后,特别是对自动增长标识列进行了调整后,检查数据库的一致性和完整性是非常重要的。这可以确保所有的数据都正确无误地被保存,并且没有任何潜在的数据丢失或错误。 ```sql SELECT * FROM...

    oracle自增长与sqlserver一样好用

    本文将深入探讨Oracle中实现自增长序列(Sequence)与SQL Server中的自增列(Identity Column)的相似之处,以及如何在Oracle中通过序列和触发器来模拟SQL Server的自增列特性。 ### Oracle中的自增长序列...

    【总结】数据库自增字段的 3 种实现方式

    然而,与其它数据库系统不同,SQLite的`AUTOINCREMENT`会在每次插入时检查是否存在已删除的记录,如果存在则重用其ID,这可能导致不连续的序列。创建表的例子如下: ```sql CREATE TABLE users ( user_id INTEGER...

    Sqlite3支持的数据类型

    需要注意的是,AUTOINCREMENT并不总是生成连续的序列,只有在删除了具有最大自增值的行后,才会重新使用已被占用的ID。 7. affinity转换 SQLite具有数据类型“affinity”概念,它决定了如何处理不同类型之间的操作...

    66 不断在表中插入数据时,物理存储是如何进行页分裂的?l.pdf

    但是,如果主键不是自增的,或者插入的数据行的主键值不是连续的,就有可能出现新数据页中的主键值小于旧数据页中的主键值的情况。为了维持数据页之间的有序性,确保后一个数据页的主键值大于前一个数据页的主键值,...

    MySQL自增长键理解

    在使用自增键时,需要注意数据一致性,避免因删除导致的自增序列不连续。另外,如果需要在已存在的数据基础上插入新记录,可以考虑使用`INSERT IGNORE`或`ON DUPLICATE KEY UPDATE`语句,以防止重复的键值冲突。 总...

    Oracle数据库中创建自增主键的实例教程

    通过更新语句,我们将`id`列的值设置为`SEQ_ID.NEXTVAL`,从而实现了自增主键的效果。 ```sql -- 新建一个缺少主键的表 CREATE TABLE test1 (name1 VARCHAR2(40), city VARCHAR2(40)); -- 插入数据 -- ...

Global site tag (gtag.js) - Google Analytics