上移下移等操作的通用存储过程

写在前面的废话:
忙着做项目,却好久没更新博客了。趁着今天想起,赶快写一篇。
----------------------------------------------------------

数据库:SQL Server 2008

实现的功能:

上移、下移、上移至N位、下移至N位(置顶和置底只需要在传参数的时候传递表的总记录数即可)
注意,此处的排序是修改N条记录的排序字段(我的业务逻辑需要,不考虑大数据量的修改)

数据库表设计
Menu表
MenuNumber 菜单序号 VARCHAR 6
OrderNum 排序编号 INTEGER




Use [数据库名]
GO
IF EXISTS (SELECT * FROM sysobjects WHERE name = 'proc_chartdb_menu_list' AND user_name(uid) = 'dbo')
DROP PROCEDURE [dbo].proc_chartdb_menu_list
GO

CREATE PROCEDURE proc_chartdb_menu_list --创建存储过程
(
@Sign int = 0, -- 0: 上移 1:下移
@MoveNum int = 1, -- 移动位数
@TableName nvarchar(50), -- 表名
@ItemName nvarchar(50), -- 主键字段名
@ItemID varchar(12), -- 主键ID值
@SortName nvarchar(50), -- 排序ID名称
@TypeName nvarchar(50)='', -- 条件字段名
@TypeValue nvarchar(50)= '' -- 条件值
)
AS

BEGIN
SET NOCOUNT ON

DECLARE
@SQL nvarchar(4000),
@ThisSort int, -- 当前排序ID
@PREVID varchar(12), -- 前一个主键ID
@NextID varchar(12), -- 后一个主键ID
@Count int = 0, -- 计数
@TempV varchar(12) = '0' -- 临时变量
--添加事务,并指定语句不能读取已由其他事务修改但尚未提交的行,并且指定,其他任何事务都不能在当前事务完成之前修改由当前事务读取的数据
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
BEGIN TRAN A
--排序操作
WHILE (@MoveNum > 0)
BEGIN
IF EXISTS(SELECT * FROM tempdb..sysobjects WHERE id=object_id('tempdb.dbo.#tempTab'))
BEGIN
DROP TABLE #tempTab
END
--临时索引表--
CREATE TABLE #tempTab
(
RowNum int,
ItemID varchar(12),
Sort int
)
--将表中主键和排序字段的值插入到临时表中
SET @SQL = 'INSERT INTO #tempTab (RowNum,ItemID,Sort) SELECT Row,'+@ItemName+ ','+ @SortName +' FROM (SELECT ROW_NUMBER() OVER (ORDER BY '+@SortName+' ASC)AS Row ,'
+@ItemName+ ','+ @SortName +' FROM '+ @TableName +') AS TEMPTABLE'

IF (@TypeName<>'' AND @TypeValue<>'') SET @SQL = @SQL +' WHERE '+ @TypeName +'='+ @TypeValue
--SET @SQL = @SQL +' ORDER BY '+@SortName+' ASC '
EXEC(@SQL)
SET @SQL = ''
SELECT @Count = COUNT(*) FROM #tempTab
SELECT @ThisSort = RowNum FROM #tempTab WHERE ItemID = @ItemID
IF(@ThisSort>1) SELECT @PREVID = ItemID FROM #tempTab WHERE RowNum=(@ThisSort-1)
IF(@ThisSort<@Count) SELECT @NextID = ItemID FROM #tempTab WHERE RowNum=(@ThisSort+1)

IF(@Sign=0)
BEGIN
IF(@ThisSort>1)
BEGIN
SELECT @TempV = Sort from #tempTab where ItemID = @PREVID
SET @SQL = 'UPDATE '+ @TableName +' SET '+ @SortName+ '='+ CONVERT(varchar(100),@TempV) +' WHERE '+ @ItemName +' = '+ CONVERT(varchar(100),@ItemID) + ';'
SELECT @TempV = Sort from #tempTab where ItemID = @ItemID
SET @SQL = @SQL + 'UPDATE '+ @TableName +' SET '+ @SortName +'='+ CONVERT(varchar(100),@TempV) +' WHERE '+ @ItemName +' = '+ CONVERT(varchar(100),@PREVID)

END
END
ELSE
BEGIN
IF(@ThisSort<@Count)
BEGIN
SELECT @TempV = Sort from #tempTab where ItemID = @NextID
SET @SQL = 'UPDATE '+ @TableName+ ' SET '+ @SortName+ '='+ CONVERT(varchar(100),(@TempV)) +' WHERE '+ @ItemName +' = '+ CONVERT(varchar(100),@ItemID) +';'
SELECT @TempV = Sort from #tempTab where ItemID = @ItemID
SET @SQL = @SQL + 'UPDATE '+ @TableName +' SET '+ @SortName +'='+ CONVERT(varchar(100),@TempV) +' WHERE '+ @ItemName +' = '+ CONVERT(varchar(100),@NextID)
END
END

EXEC(@SQL)
SET @MoveNum = @MoveNum-1
END
COMMIT TRAN A
END

go
--执行 存储过程名
--参数1:(0,上移;1,下移),
--参数2:移动位数
--参数3:表名
--参数4:主键名
--参数5:主键值
--参数6:排序字段名
--参数7:条件字段名
--参数8:条件值
exec proc_chartdb_menu_list 1, 3, 'dbo.Menu', 'MenuNumber','121', 'OrderNum', '', ''

Go
SELECT * FROM Menu Order by OrderNum



执行计划中,主要在插入临时表和排序中,开销较大。存储过程没有进行优化(实际上是自己目前精力和能力有限)
存储过程中包含17个查询,4个更新,1个插入,有操作可能会重复执行。

开销最大的部分是 循环体 部分,重复的创建临时表,插入、更新等。

欢迎交流和提出改进方法

-----
修改:
添加了事务锁

说明:

以下内容参考网上方法,进行改进,不是100%的原创。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: C# DataTable 操作上移下移可以通过以下步骤实现: 1. 获取当前选中行的索引值。 2. 判断是上移还是下移操作。 3. 如果是上移操作,将当前行和上一行的数据交换。 4. 如果是下移操作,将当前行和下一行的数据交换。 5. 更新 DataTable 的数据源。 以下是示例代码: ``` // 获取当前选中行的索引值 int rowIndex = dataGridView1.CurrentCell.RowIndex; // 判断是上移还是下移操作 if (e.KeyCode == Keys.Up) { // 上移操作 if (rowIndex > ) { // 获取当前行和上一行的数据 DataRow currentRow = ((DataRowView)dataGridView1.Rows[rowIndex].DataBoundItem).Row; DataRow prevRow = ((DataRowView)dataGridView1.Rows[rowIndex - 1].DataBoundItem).Row; // 交换数据 object[] temp = currentRow.ItemArray; currentRow.ItemArray = prevRow.ItemArray; prevRow.ItemArray = temp; // 更新 DataTable 的数据源 DataTable dt = (DataTable)dataGridView1.DataSource; dt.AcceptChanges(); } } else if (e.KeyCode == Keys.Down) { // 下移操作 if (rowIndex < dataGridView1.Rows.Count - 1) { // 获取当前行和下一行的数据 DataRow currentRow = ((DataRowView)dataGridView1.Rows[rowIndex].DataBoundItem).Row; DataRow nextRow = ((DataRowView)dataGridView1.Rows[rowIndex + 1].DataBoundItem).Row; // 交换数据 object[] temp = currentRow.ItemArray; currentRow.ItemArray = nextRow.ItemArray; nextRow.ItemArray = temp; // 更新 DataTable 的数据源 DataTable dt = (DataTable)dataGridView1.DataSource; dt.AcceptChanges(); } } ``` ### 回答2: 抱歉,您没有明确提供问题或话题,无法为您提供准确详细的回答。请您再次提供具体的问题或话题,我会尽力帮助您! ### 回答3: 在计算机科学中,C语言是一种高级编程语言,它由贝尔实验室的Dennis Ritchie在20世纪70年代末发明。C语言的目标是为开发操作系统和编写和许多其他应用程序提供一个可移植、高效的工具。C语言具有许多使用和优点,其中一些包括: 1. 简单明了:C语言的语法和语义是简单的,容易理解和学习。此外,C语言没有太多的约束性,程序员可以自由地编写代码。 2. 低级别:C语言的低级别语法让程序员可以操纵内存,从而在效率上得到优化。C语言适合于编写一些对效率要求高的代码,例如操作系统和驱动程序。 3. 高度可移植性:C语言的编译器已经被移植到许多不同的计算机体系结构上。这意味着程序可以编写一次,在不同的计算机上运行。 4. 开放源代码:许多C语言编译器、库和工具是免费的,可以在不付出任何成本的情况下使用并改进。这使程序员可以在不牺牲质量的情况下提高效率。 C语言的应用非常广泛。它可以用于编写操作系统、设备驱动程序、游戏引擎、桌面应用程序、嵌入式系统等等。许多编程语言都借鉴了C语言的语法和结构,例如Java和C++。因此,C语言被认为是计算机科学的重要里程碑,对现代IT行业的发展有重要贡献。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值