用SQLServer实现数据表中,将任意一条记录信息移动到该表中的任意位置
发表于:2007-07-02来源:作者:点击数:
标签:
-- 定位数据 -- 设计思路: -- 保存要被移动记录的原主键值和新主键值(如果有主键的话),然后比较两个主键值的大小(记录信息按升序排列), -- 如果原主键值大,表明该记录被移动到前面的新位置,可将原位置的记录信息保存下来,并将从新位置的记录信息到 --
-- 定位数据
-- 设计思路:
-- 保存要被移动记录的原主键值和新主键值(如果有主键的话),然后比较两个主键值的大小(记录信息按升序排列),
-- 如果原主键值大,表明该记录被移动到前面的新位置,可将原位置的记录信息保存下来,并将从新位置的记录信息到
-- 原记录的前一条记录的信息顺次往下移动,把保存的原记录移动到新位置即可。
-- 如果原主键值小,表明该记录被移动到后面的新位置,可将原位置的记录信息保存下来,并将从新位置的记录信息到
-- 原记录的下一条记录的信息顺次往上移动,把保存的原记录移动到新位置即可。实际上就是记录块的移动.
-- 但是,如果数据表中的数据非常庞大,该存储过程的执行效率将会下降.
Use zzydb
--创建举例表(学生信息表)
Create Table T_StudentsInfo
(i_id int identity(1,1), --系统自增流水号
c_Stu_ID nvarchar(10), --学号
c_ClassName nvarchar(50), --班级
d_BirthDay datetime) --出生日期
go
--向举例表中插入4条学生信息,以验证下面的存储过程(sp_MyAdjustRecordOrder)
Insert into T_StudentsInfo values(@#001@#, @#大二三班@#, @#1978-01-25@#)
Insert into T_StudentsInfo values(@#002@#, @#大一六班@#, @#1979-02-05@#)
Insert into T_StudentsInfo values(@#003@#, @#大四三班@#, @#1981-07-15@#)
Insert into T_StudentsInfo values(@#004@#, @#大三一班@#, @#1976-01-05@#)
select * from T_StudentsInfo
if object_id(@#sp_MyAdjustRecordOrder@#) <> 0
drop proc sp_MyAdjustRecordOrder
go
Create Proc sp_MyAdjustRecordOrder(@OldStuId nvarchar(10), @NewStuId nvarchar(10))
as
--@OldStuid 学生学号(用以表示被移动的记录),
--@NewStuid 学生学号(用以表示将被移动的记录插入的新位置)
begin
declare @Old_i_id int, @New_i_id int
declare @i_BlockCount int--即将被移动的记录块条数
declare @i int--循环变量
--获得id值
Select @Old_i_id = (select I_id from T_StudentsInfo where c_Stu_ID = @OldStuId)
Select @New_i_id = (select I_id from T_StudentsInfo where c_Stu_ID = @NewStuId)
select @i_BlockCount = abs(@Old_i_id - @New_i_id)
--保存被移动的学生信息
Select c_Stu_ID, c_ClassName, d_BirthDay
into New_StudentsInfo--临时创建的表,用完后删除
from T_StudentsInfo
where c_Stu_ID = @OldStuId
if @New_i_id < @Old_i_id --将原记录信息移动到了前面
begin
select @i = 0
while @i <= @i_BlockCount - 1
begin
update T_StudentsInfo
set c_Stu_ID = T2.c_Stu_ID,
c_ClassName = T2.c_ClassName,
d_BirthDay = T2.d_BirthDay
From T_StudentsInfo , T_StudentsInfo T2
where (T_StudentsInfo.i_id = @Old_i_id - @i) and
(T2.i_id = @Old_i_id - @i - 1)
select @i = @i + 1
end
end
if @New_i_id > @Old_i_id --将原记录信息移动到了后面
begin
select @i = 0
while @i <= @i_BlockCount - 1
begin
update T_StudentsInfo
set c_Stu_ID = T2.c_Stu_ID,
c_ClassName = T2.c_ClassName,
d_BirthDay = T2.d_BirthDay
From T_StudentsInfo, T_StudentsInfo T2
where (T_StudentsInfo.i_id = @Old_i_id + @i) and
(T2.i_id = @Old_i_id + @i + 1)
select @i = @i + 1
end
end
update T_StudentsInfo
set c_Stu_ID = T3.c_Stu_ID,
c_ClassName = T3.c_ClassName,
d_BirthDay = T3.d_BirthDay
From T_StudentsInfo T1, New_StudentsInfo T3
where (T1.i_id = @New_i_id )
Drop table New_StudentsInfo
--if @New_i_id = @Old_i_id --位置未发生改变,不做任何处理
end
go
--使用举例
--要求:将c_Stu_Id为@#004@#的学生信息移动到c_Stu_Id为@#002@#的学生信息之前的位置.
--调用存储过程 sp_MyAdjustRecordOrder(@#004@#,@#002@#)即可.
--注意:这里的i_id必须是顺序的。
--备份表数据信息,以便于比较
select *
into StudentsInfoBackup
from T_StudentsInfo
--比较结果是否一致
select * from StudentsInfoBackup
select * from T_StudentsInfo
--移动数据记录信息,调用存储过程
exec sp_MyAdjustRecordOrder @#003@#, @#002@#
--比较结果是否改动
select * from StudentsInfoBackup
select * from T_StudentsInfo
原文转自:http://www.ltesting.net