日期:2014-05-17 浏览次数:20572 次
id xm 1 张三 2 李四 3 王五 4 杨柳
ALTER PROCEDURE [dbo].[cs]
@xm varchar(50)
AS
BEGIN
SET NOCOUNT ON;
declare @id int
select @id=id from gen where xm is null
if @id is null
begin
insert into gen (xm) values (null)
select @id=SCOPE_IDENTITY()
end
update gen set xm=@xm where id=@id
select @id
END
declare @t table(id int identity(1,1),[xm] varchar(2))
insert @t
select 'aa' union all
select 'bb' union all
select 'cc' union all
select 'dd' union all
select 'ee' union all
select 'ff'
delete from @t where xm in ('bb','dd')
select row_number() over (order by id) as nid,* from @t
/*
nid id xm
-------------------- ----------- ----
1 1 aa
2 3 cc
3 5 ee
4 6 ff
*/
------解决方案--------------------
你的担心当然存在,数据库是并发的,查询和修改之间有时间差,所以可能出现更新同一条数据而造成更新丢失。
解决方法:
1、ID号不连续一半是可以接受的,你现在找回原来的号的设计有点多余,最好改变设计,减少出错机会
2、如果是明确需求,可以用事务控制,注意用事务的代价是损失性能
ALTER PROCEDURE [dbo].[cs]
@xm varchar(50)
AS
BEGIN
SET NOCOUNT ON;
declare @id int
SET XACT_ABORT ON
BEGIN TRANSACTION
select TOP 1 @id=id from gen WITH (UPLOCK) where xm is null
if @id is null
begin
insert into gen (xm) values (null)
select @id=SCOPE_IDENTITY()
end
update gen set xm=@xm where id=@id
COMMIT TRANSACTION
select @id
END
------解决方案--------------------
直接删除,按照id的排序在查询时做一个序号列都是可行的,或者楼主可以将这个表单独做一个单表视图。
--sql2005 create view tbview as select id,xm,rid=row_number() over (order by id) from tb --sql2000 create view tbview as select id,xm,rid=(select count(*) from tb where id <= t.id) from tb t
------解决方案--------------------
现在ID基本上除了个主键,其他的没有什么意义了吧
------解决方案--------------------
id 连续不连续都无所谓的,你为了让它强行一致,付出的代价太大了。
就跟6楼说的,必须的锁表才能控制并发不冲突,但是这样很容易block
------解决方案--------------------