ADOQuery、SQL语句和数据库中行的重新排序
我有一个名为p_Columns的数据库表。此表包含列ADOQuery、SQL语句和数据库中行的重新排序,sql,database,delphi,ado,Sql,Database,Delphi,Ado,我有一个名为p_Columns的数据库表。此表包含列 ID Column_Name Column_Type Column_Visible Column_Order 此数据表由显示dbgrid的应用程序填充和更新。 这个应用程序有一个按钮。单击时,它将获取所选行。把它往上移一行这是我需要帮助的地方 现在,我的初始SQL语句SELECT*FROM p_Columns Order by Column_Order asc设置了正确的顺序。起初 我需要找出是否有update Sql语句允许我交换所选记录
ID
Column_Name
Column_Type
Column_Visible
Column_Order
此数据表由显示dbgrid的应用程序填充和更新。
这个应用程序有一个按钮。单击时,它将获取所选行。把它往上移一行这是我需要帮助的地方
现在,我的初始SQL语句SELECT*FROM p_Columns Order by Column_Order asc设置了正确的顺序。起初
我需要找出是否有update Sql语句允许我交换所选记录的列顺序。就在它之前
希望这是有意义的。我相信这会对你有帮助
update P_Columns
set Column_Order = ((select count(*) from P_Columns) + 1) - Column_Order
交换两个位置。使用最后一个和:order>1,因此位置1不能与不存在的位置0交换
update datatable
set column_order = case
when column_order = :order then column_order-1
else column_order+1
end
where column_order in (:order, :order-1)
and :order > 1
CASE语句应该存在于大多数主要的DBMS中
注意:stock TADOQuery中有一个bug,它不会一次性设置参数all 4:order parameters。需要4个参数,所有参数都带有相同的值,除非已知DBMS优化了特定DBMS的查询。以下是Delphi代码,它使用TADOCommand调用update语句两次来实现您想要的功能。这是针对MS SQL Server进行测试的。如果您不使用TADO*组件,您应该能够转换为您使用的任何数据库组件。ADODataSet1是网格中显示的数据
var
CurrentID: Integer;
CurrentOrder: Integer;
PrevID: Integer;
PrevOrder: Integer;
begin
if ADODataSet1.RecNo > 1 then // Do not move the first row
begin
CurrentID := ADODataSet1['ID'];
CurrentOrder := ADODataSet1['Column_Order'];
ADODataSet1.Prior;
PrevID := ADODataSet1['ID'];
PrevOrder := ADODataSet1['Column_Order'];
ADOCommand1.CommandText := 'update P_Columns set Column_Order = :Column_Order where ID = :ID';
ADOCommand1.Parameters.ParamByName('Column_Order').Value := PrevOrder;
ADOCommand1.Parameters.ParamByName('ID').Value := CurrentID;
ADOCommand1.Execute;
ADOCommand1.Parameters.ParamByName('Column_Order').Value := CurrentOrder;
ADOCommand1.Parameters.ParamByName('ID').Value := PrevID;
ADOCommand1.Execute;
ADODataSet1.Requery([]);
end;
end;
我可能错了,但在这种情况下,似乎你不必只有一种陈述式的解决方案。我也不认为这意味着什么,因为您只讨论了一个UPDATE语句,这并不意味着您不能让任何其他语句准备更新,是吗?但如果你真的想到了这一点,请原谅我,但我会继续前进 首先,我想知道你的专栏顺序是否确实没有空白。因为如果没有差距,且值从1开始,那么您可以仅通过此修改就可以使用cyberkiwi的解决方案,但所有信用都应归于此人:
declare @order int;
set @order = :order;
update P_Columns
set Column_Order =
case
when Column_Order = @order then Column_Order - 1
else Column_Order + 1
end
where Column_Order in (@order, @order - 1) and @order > 1
也就是说,您需要声明@var,以便每个脚本只使用:order一次。你可能已经知道了。你在这儿
但是,如果该解决方案不能按原样应用,那么基本上,我认为,您只需要添加更多语句来预先计算由于交换而产生的其他订单值,然后进行更新
下面是它可能的样子:
declare @order int, @prev_order int;
set @order = :order;
/* here goes looking up for the other Column_Order */
select @prev_order = max(Column_Order)
from P_Columns
where Column_Order < @order;
/* and now update, which is basically the same,
only adapted for use with @prevorder,
and also we check if @prevorder has a value */
if @prevorder is not null
update P_Columns
set Column_Order =
case Column_Order
when @order then @prevorder
else @order
end
where Column_Order in (@order, @prevorder)
如果您有任何问题,欢迎提问。这是连接到哪个dbms的?我在这里做的是计算记录的计数,将其增加1,然后减去当前列的顺序…因此列的顺序列从1,2,3…5开始,然后转到5,4,3…1。您假设列的顺序a是数字,b在它的序列中没有间隙。这些假设是否到期?您可以使用行\号而不是列\顺序或等效项来修复代码,然后将您的逻辑应用于结果列。@1-有一条关于DBMS挂起的注释。这个问题表明没有差距,但OP可以澄清这是否属实。这个问题表明没有差距——它在哪里说的?数据类型也可以是整数或数字。谢谢你,这算是最好的了。我感谢大家的帖子。