当删除一条记录时,更改表中字段的内容?

时间:2020-12-05 15:02:50
当删除一条记录时,更改表中字段的内容?


现在的需求是这样的:
比如说有表a如下:
cid       c_no
1          20090501
2          20090502
3          20090503


当删除表中第一条记录时,第二条和第三条中的c_no就变成20090501,20090502
觉得好像需要使用游标才能搬到,请高手给指点一下,谢谢啦!

78 个解决方案

#1


delete from tb
where id=1

update tb
set c_no=dateadd(day,1,c_no)
where id>1

#2


另外三个疑问:
1,20090501这个日期吧?你的意思是加一天?比如20081231加1就变成20090101??
2,是不是想用触发器?
3,是不是只更新id大于被删除的id的?比如删除2,只更新3?

#3


if object_id('tb') is not null
drop table tb
go

create table tb(cid int,c_no varchar(8))
insert tb select 1,'20090501'
insert tb select 2,'20090502'
insert tb select 3,'20090503'
insert tb select 4,'20081231'

select * from tb

--创建触发器
if object_id('tri_update') is not null
drop trigger tri_update
go

create trigger tri_update on tb
for delete
as
begin
declare @cid int
select @cid=cid from deleted

update tb
set c_no=convert(char(8),dateadd(day,1,c_no),112)
where cid>@cid
end
go

--删除cid=2
delete from tb
where cid=2

--查看数据
select * from tb

--删除触发器和表
drop trigger tri_update
drop table tb
/*

(1 行受影响)

(1 行受影响)

(1 行受影响)

(1 行受影响)
cid         c_no
----------- --------
1           20090501
2           20090502
3           20090503
4           20081231

(4 行受影响)


(2 行受影响)

(1 行受影响)
cid         c_no
----------- --------
1           20090501
3           20090504
4           20090101

(3 行受影响)
*/

#4


如果你的表只是这三条数据的话当然好处理。

关键很多问题之所以复杂是因为特殊点太多了!

建议你把题目再说明确点

#5




create table test(cid int ,c_no datetime)
insert test
select       1,          '20090501' 
union select 2,          '20090502' 
union select 3,          '20090503' 


create trigger t_test
on test 
after delete as
update test 
set c_no = dateadd(day,-1,c_no)
from test

delete   from  test where c_no='20090501'
select * from test
---
2 2009-05-01 00:00:00.000
3 2009-05-02 00:00:00.000

#6


引用楼主 homel 的帖子:
当删除一条记录时,更改表中字段的内容? 


现在的需求是这样的: 
比如说有表a如下: 
cid      c_no 
1          20090501 
2          20090502 
3          20090503 


当删除表中第一条记录时,第二条和第三条中的c_no就变成20090501,20090502 
觉得好像需要使用游标才能搬到,请高手给指点一下,谢谢啦! 


这样的需求将给程序大来很大的弊端!

#7


没必要吧,这样的需求感觉别扭!
好像费不少力气,却不知道有多大作用。

#8


引用楼主 homel 的帖子:
当删除一条记录时,更改表中字段的内容? 


现在的需求是这样的: 
比如说有表a如下: 
cid      c_no 
1          20090501 
2          20090502 
3          20090503 


当删除表中第一条记录时,第二条和第三条中的c_no就变成20090501,20090502 
觉得好像需要使用游标才能搬到,请高手给指点一下,谢谢啦! 

你在干啥
在考验你的数据库抗压能力吗?

#9


引用 8 楼 ws_hgo 的回复:
引用楼主 homel 的帖子:
当删除一条记录时,更改表中字段的内容? 


现在的需求是这样的: 
比如说有表a如下: 
cid      c_no 
1          20090501 
2          20090502 
3          20090503 


当删除表中第一条记录时,第二条和第三条中的c_no就变成20090501,20090502 
觉得好像需要使用游标才能搬到,请高手给指点一下,谢谢啦! 
 
你在干啥 
在考验你的数据库抗压能力吗?

我也没有办法,客户的需求得满足啊!
已经解释过了,那是客户非要实现那样的功能,其实后面的01,02,03只是流水码
也有考虑过数据很多的情况下,这样做肯定会出现的问题的,但是又不知道该如何对客户解释!

#10


引用 3 楼 conan304 的回复:
SQL codeif object_id('tb') is not null
drop table tb
go

create table tb(cid int,c_no varchar(8))
insert tb select 1,'20090501'
insert tb select 2,'20090502'
insert tb select 3,'20090503'
insert tb select 4,'20081231'

select * from tb

--创建触发器
if object_id('tri_update') is not null
drop trigger tri_update
go

create trigger tri_update on tb
for delete
as
begin
    decl…



谢谢你的回复,但是你理解错了,c_no不是日期,后面的是01,02,03是流水码

#11



#12


顶吧!!

如果表里面的数据量有千万条,你怎么办?

#13


流水号结合row_number()

不行给客户说,流水号不能更新,否则无法唯一识别这条记录

既然后两位是流水号,是不是前6位是日期?那就是说最多修改99个?
那没必要修改吧,筛选出前6位相同的,按id排个序,看他是第几条就是第几个啦

#14


引用 13 楼 yuehuolong 的回复:
流水号结合row_number() 

不行给客户说,流水号不能更新,否则无法唯一识别这条记录 

既然后两位是流水号,是不是前6位是日期?那就是说最多修改99个? 
那没必要修改吧,筛选出前6位相同的,按id排个序,看他是第几条就是第几个啦

主要是因为客户说是订单号必须是连续的,根据流水号后面的数字可以看到每个月到底下了多少单子...

#15


update test set c_no=convert(varchar(8),dateadd(day,-1,c_no),112)

#16


创建一个触发器,在删除操作的时候执行更新

#17


订单号是连续的?难道没有中间操作和废弃的操作?你可以弄个表专门记录一下今天做了多少正式单的嘛

#18


我有个想法,不知道你每条记录顺序是否可以改变,如果顺序无所谓的话,可以在删除一条记录的时候,把该序列最后一条记录的订单号改成删除的那条订单号就行了。。。。我觉得这样比一条一条该效率高点吧

#19


看来这个字段的值不必存于数据库,因为只是给人看的
不过用户可能需要以此字段来查找,所以又需要能被检索。

方案:
1、存储与显示:数据库里存 年月部分,配合  row_number()得序号字段,组合成该值以供查看。
2、检索:对于用户输入 20090512 之类的值,解析为年月以及序号,用 1的办法 取出带序号的记录集,
即可匹配。

#20


如果数据量大,太费性能了,不建议这样做。不知你要实现什么需求,完全可以在业务层控制实现!

#21


LZ的问题很实用,支持,帮顶

#22


哥们,咱能不能不在数据库中实现,在程序中实现呢??就是把删除和更新做为两个操作步骤,放在同一个事务中??
这样岂不是更容易理解,也更容易实现??????

#23


#24


既然流水号必须连续,而中间是否被删除,作废并不重要,那这个流水号就只具有显示意义,表中根本就不存这个号,显示的时候根据顺序重新生成就可以了。不就是为了看着好看吗?

#25


delete from tb
where id=1

update tb
set c_no=dateadd(day,1,c_no)
where id>1

#26


当删除表中第一条记录时,第二条和第三条中的c_no就变成20090501,20090502 
觉得好像需要使用游标才能搬到,请高手给指点一下,谢谢啦! 

#27


可以用游标,或者在程序中写一个函数进行递归

#28


帮顶

#29


你这种业务逻辑不可取,建义LZ重新考虑下业务。
否则数据时多的话,这种方法就很不可取的,你可在表中添加一个标识字段,删除数据时只把标识更新下,建议不要删除数据。

#30


#31


给客户看的问题好解决,你在数据库信息输出成报表的时候在程序里做点手脚不就行了么,反正客户看到得是报表又不是数据库记录

#32


引用 24 楼 ks2000 的回复:
既然流水号必须连续,而中间是否被删除,作废并不重要,那这个流水号就只具有显示意义,表中根本就不存这个号,显示的时候根据顺序重新生成就可以了。不就是为了看着好看吗?

支持下,建议在将符合条件的排序即可

#33


这个在财务软件中有用到,就是记账凭证号,当作废一张凭证后就要整理断号以保证号码的连续性,不过它有一个前提就是每个月必须结完账后才能做下一个月的,这样整理起来也就是一个月的数据量,对数据库压力不大,如果整个库每改一次都整理一次,有个几万十万的数据的时候,哭都哭不出来了!

#34


引用 18 楼 zamtion 的回复:
我有个想法,不知道你每条记录顺序是否可以改变,如果顺序无所谓的话,可以在删除一条记录的时候,把该序列最后一条记录的订单号改成删除的那条订单号就行了。。。。我觉得这样比一条一条该效率高点吧

我觉得这个想法也不错啊
可以考虑下

#35


路过看看。。。

#36



你们把简单的问题复杂化了。。。

delete from tb where c_no = 20090501;
update tb set c_no = (c_no - 1) where c_no > 20090501;

#37


学习

#38


引用 36 楼 fanhui1022 的回复:
你们把简单的问题复杂化了。。。 

delete from tb where c_no = 20090501; 
update tb set c_no = (c_no - 1) where c_no > 20090501;


支持

#39


引用 36 楼 fanhui1022 的回复:
你们把简单的问题复杂化了。。。 

delete from tb where c_no = 20090501; 
update tb set c_no = (c_no - 1) where c_no > 20090501;


这个最好,再加个And判断一下就完美了。

#40



declare @i int
set @i=值

update 表 set @i=@i-1,yy=@i 

#41



declare @i int
set @i=值

update 表 set @i=@i-1,c_no=@i 


以前见 子陌红尘(retired) 这样写过。

#42


declare @i int
set @i=值

update 表 set @i=@i-1,c_no=@i WHERE c_no>值

#43


mark!!

#44


.

#45


按 csdn 要求 回帖是一种美德!每天回帖即可获得 10 分可用分! 

#46


引用 36 楼 fanhui1022 的回复:
你们把简单的问题复杂化了。。。 

delete from tb where c_no = 20090501; 
update tb set c_no = (c_no - 1) where c_no > 20090501;



这样也可以,学的东西,灵活灵用

#47


up

#48


引用 14 楼 homel 的回复:
引用 13 楼 yuehuolong 的回复:
流水号结合row_number()

不行给客户说,流水号不能更新,否则无法唯一识别这条记录

既然后两位是流水号,是不是前6位是日期?那就是说最多修改99个?
那没必要修改吧,筛选出前6位相同的,按id排个序,看他是第几条就是第几个啦

主要是因为客户说是订单号的,根据流水号后面的数字可以看到...


客户真正的需求是否就是统计每个月到底下了多少单子?而非订单号必须是连续。
是的话就可以改为统计,这样数据库压力会少一点!

#49


mark

#50


顶顶顶

#1


delete from tb
where id=1

update tb
set c_no=dateadd(day,1,c_no)
where id>1

#2


另外三个疑问:
1,20090501这个日期吧?你的意思是加一天?比如20081231加1就变成20090101??
2,是不是想用触发器?
3,是不是只更新id大于被删除的id的?比如删除2,只更新3?

#3


if object_id('tb') is not null
drop table tb
go

create table tb(cid int,c_no varchar(8))
insert tb select 1,'20090501'
insert tb select 2,'20090502'
insert tb select 3,'20090503'
insert tb select 4,'20081231'

select * from tb

--创建触发器
if object_id('tri_update') is not null
drop trigger tri_update
go

create trigger tri_update on tb
for delete
as
begin
declare @cid int
select @cid=cid from deleted

update tb
set c_no=convert(char(8),dateadd(day,1,c_no),112)
where cid>@cid
end
go

--删除cid=2
delete from tb
where cid=2

--查看数据
select * from tb

--删除触发器和表
drop trigger tri_update
drop table tb
/*

(1 行受影响)

(1 行受影响)

(1 行受影响)

(1 行受影响)
cid         c_no
----------- --------
1           20090501
2           20090502
3           20090503
4           20081231

(4 行受影响)


(2 行受影响)

(1 行受影响)
cid         c_no
----------- --------
1           20090501
3           20090504
4           20090101

(3 行受影响)
*/

#4


如果你的表只是这三条数据的话当然好处理。

关键很多问题之所以复杂是因为特殊点太多了!

建议你把题目再说明确点

#5




create table test(cid int ,c_no datetime)
insert test
select       1,          '20090501' 
union select 2,          '20090502' 
union select 3,          '20090503' 


create trigger t_test
on test 
after delete as
update test 
set c_no = dateadd(day,-1,c_no)
from test

delete   from  test where c_no='20090501'
select * from test
---
2 2009-05-01 00:00:00.000
3 2009-05-02 00:00:00.000

#6


引用楼主 homel 的帖子:
当删除一条记录时,更改表中字段的内容? 


现在的需求是这样的: 
比如说有表a如下: 
cid      c_no 
1          20090501 
2          20090502 
3          20090503 


当删除表中第一条记录时,第二条和第三条中的c_no就变成20090501,20090502 
觉得好像需要使用游标才能搬到,请高手给指点一下,谢谢啦! 


这样的需求将给程序大来很大的弊端!

#7


没必要吧,这样的需求感觉别扭!
好像费不少力气,却不知道有多大作用。

#8


引用楼主 homel 的帖子:
当删除一条记录时,更改表中字段的内容? 


现在的需求是这样的: 
比如说有表a如下: 
cid      c_no 
1          20090501 
2          20090502 
3          20090503 


当删除表中第一条记录时,第二条和第三条中的c_no就变成20090501,20090502 
觉得好像需要使用游标才能搬到,请高手给指点一下,谢谢啦! 

你在干啥
在考验你的数据库抗压能力吗?

#9


引用 8 楼 ws_hgo 的回复:
引用楼主 homel 的帖子:
当删除一条记录时,更改表中字段的内容? 


现在的需求是这样的: 
比如说有表a如下: 
cid      c_no 
1          20090501 
2          20090502 
3          20090503 


当删除表中第一条记录时,第二条和第三条中的c_no就变成20090501,20090502 
觉得好像需要使用游标才能搬到,请高手给指点一下,谢谢啦! 
 
你在干啥 
在考验你的数据库抗压能力吗?

我也没有办法,客户的需求得满足啊!
已经解释过了,那是客户非要实现那样的功能,其实后面的01,02,03只是流水码
也有考虑过数据很多的情况下,这样做肯定会出现的问题的,但是又不知道该如何对客户解释!

#10


引用 3 楼 conan304 的回复:
SQL codeif object_id('tb') is not null
drop table tb
go

create table tb(cid int,c_no varchar(8))
insert tb select 1,'20090501'
insert tb select 2,'20090502'
insert tb select 3,'20090503'
insert tb select 4,'20081231'

select * from tb

--创建触发器
if object_id('tri_update') is not null
drop trigger tri_update
go

create trigger tri_update on tb
for delete
as
begin
    decl…



谢谢你的回复,但是你理解错了,c_no不是日期,后面的是01,02,03是流水码

#11



#12


顶吧!!

如果表里面的数据量有千万条,你怎么办?

#13


流水号结合row_number()

不行给客户说,流水号不能更新,否则无法唯一识别这条记录

既然后两位是流水号,是不是前6位是日期?那就是说最多修改99个?
那没必要修改吧,筛选出前6位相同的,按id排个序,看他是第几条就是第几个啦

#14


引用 13 楼 yuehuolong 的回复:
流水号结合row_number() 

不行给客户说,流水号不能更新,否则无法唯一识别这条记录 

既然后两位是流水号,是不是前6位是日期?那就是说最多修改99个? 
那没必要修改吧,筛选出前6位相同的,按id排个序,看他是第几条就是第几个啦

主要是因为客户说是订单号必须是连续的,根据流水号后面的数字可以看到每个月到底下了多少单子...

#15


update test set c_no=convert(varchar(8),dateadd(day,-1,c_no),112)

#16


创建一个触发器,在删除操作的时候执行更新

#17


订单号是连续的?难道没有中间操作和废弃的操作?你可以弄个表专门记录一下今天做了多少正式单的嘛

#18


我有个想法,不知道你每条记录顺序是否可以改变,如果顺序无所谓的话,可以在删除一条记录的时候,把该序列最后一条记录的订单号改成删除的那条订单号就行了。。。。我觉得这样比一条一条该效率高点吧

#19


看来这个字段的值不必存于数据库,因为只是给人看的
不过用户可能需要以此字段来查找,所以又需要能被检索。

方案:
1、存储与显示:数据库里存 年月部分,配合  row_number()得序号字段,组合成该值以供查看。
2、检索:对于用户输入 20090512 之类的值,解析为年月以及序号,用 1的办法 取出带序号的记录集,
即可匹配。

#20


如果数据量大,太费性能了,不建议这样做。不知你要实现什么需求,完全可以在业务层控制实现!

#21


LZ的问题很实用,支持,帮顶

#22


哥们,咱能不能不在数据库中实现,在程序中实现呢??就是把删除和更新做为两个操作步骤,放在同一个事务中??
这样岂不是更容易理解,也更容易实现??????

#23


#24


既然流水号必须连续,而中间是否被删除,作废并不重要,那这个流水号就只具有显示意义,表中根本就不存这个号,显示的时候根据顺序重新生成就可以了。不就是为了看着好看吗?

#25


delete from tb
where id=1

update tb
set c_no=dateadd(day,1,c_no)
where id>1

#26


当删除表中第一条记录时,第二条和第三条中的c_no就变成20090501,20090502 
觉得好像需要使用游标才能搬到,请高手给指点一下,谢谢啦! 

#27


可以用游标,或者在程序中写一个函数进行递归

#28


帮顶

#29


你这种业务逻辑不可取,建义LZ重新考虑下业务。
否则数据时多的话,这种方法就很不可取的,你可在表中添加一个标识字段,删除数据时只把标识更新下,建议不要删除数据。

#30


#31


给客户看的问题好解决,你在数据库信息输出成报表的时候在程序里做点手脚不就行了么,反正客户看到得是报表又不是数据库记录

#32


引用 24 楼 ks2000 的回复:
既然流水号必须连续,而中间是否被删除,作废并不重要,那这个流水号就只具有显示意义,表中根本就不存这个号,显示的时候根据顺序重新生成就可以了。不就是为了看着好看吗?

支持下,建议在将符合条件的排序即可

#33


这个在财务软件中有用到,就是记账凭证号,当作废一张凭证后就要整理断号以保证号码的连续性,不过它有一个前提就是每个月必须结完账后才能做下一个月的,这样整理起来也就是一个月的数据量,对数据库压力不大,如果整个库每改一次都整理一次,有个几万十万的数据的时候,哭都哭不出来了!

#34


引用 18 楼 zamtion 的回复:
我有个想法,不知道你每条记录顺序是否可以改变,如果顺序无所谓的话,可以在删除一条记录的时候,把该序列最后一条记录的订单号改成删除的那条订单号就行了。。。。我觉得这样比一条一条该效率高点吧

我觉得这个想法也不错啊
可以考虑下

#35


路过看看。。。

#36



你们把简单的问题复杂化了。。。

delete from tb where c_no = 20090501;
update tb set c_no = (c_no - 1) where c_no > 20090501;

#37


学习

#38


引用 36 楼 fanhui1022 的回复:
你们把简单的问题复杂化了。。。 

delete from tb where c_no = 20090501; 
update tb set c_no = (c_no - 1) where c_no > 20090501;


支持

#39


引用 36 楼 fanhui1022 的回复:
你们把简单的问题复杂化了。。。 

delete from tb where c_no = 20090501; 
update tb set c_no = (c_no - 1) where c_no > 20090501;


这个最好,再加个And判断一下就完美了。

#40



declare @i int
set @i=值

update 表 set @i=@i-1,yy=@i 

#41



declare @i int
set @i=值

update 表 set @i=@i-1,c_no=@i 


以前见 子陌红尘(retired) 这样写过。

#42


declare @i int
set @i=值

update 表 set @i=@i-1,c_no=@i WHERE c_no>值

#43


mark!!

#44


.

#45


按 csdn 要求 回帖是一种美德!每天回帖即可获得 10 分可用分! 

#46


引用 36 楼 fanhui1022 的回复:
你们把简单的问题复杂化了。。。 

delete from tb where c_no = 20090501; 
update tb set c_no = (c_no - 1) where c_no > 20090501;



这样也可以,学的东西,灵活灵用

#47


up

#48


引用 14 楼 homel 的回复:
引用 13 楼 yuehuolong 的回复:
流水号结合row_number()

不行给客户说,流水号不能更新,否则无法唯一识别这条记录

既然后两位是流水号,是不是前6位是日期?那就是说最多修改99个?
那没必要修改吧,筛选出前6位相同的,按id排个序,看他是第几条就是第几个啦

主要是因为客户说是订单号的,根据流水号后面的数字可以看到...


客户真正的需求是否就是统计每个月到底下了多少单子?而非订单号必须是连续。
是的话就可以改为统计,这样数据库压力会少一点!

#49


mark

#50


顶顶顶