我有一个名为P_Columns的数据库表。此表包含列
ID
Column_Name
Column_Type
Column_Visible
Column_Order
此数据表由显示dbgrid的应用程序填充和更新。 这个应用程序有一个按钮。单击时,它将获取所选行。并将其向上移动一行(这是我需要帮助的地方)。
现在我的初始SQL语句(SELECT * FROM P_Columns Order by Column_Order asc)设置了正确的顺序。原来。
我需要找出是否有更新的Sql语句,它允许我交换所选记录的Column_Order。与之前的记录相同。
希望这是有道理的。
答案 0 :(得分:0)
我相信这会为你做到这一点......
update P_Columns
set Column_Order = ((select count(*) from P_Columns) + 1) - Column_Order
答案 1 :(得分:0)
交换两个位置。使用最后一个AND :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中存在一个错误,它不会一次性设置所有4个:order
参数的参数。除非已知DBMS优化特定DBMS的查询,否则将需要4个参数都具有相同的值。
答案 2 :(得分:0)
这是使用TADOCommand调用更新语句两次执行所需的Delphi代码。这是针对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;
答案 3 :(得分:0)
我可能错了,但似乎在这种情况下你不必只有一个声明解决方案。我也没有看到它暗示,因为你只是在谈论 UPDATE 声明,这并不意味着你不能有任何其他声明准备你的更新,是吗?但如果你确实考虑到了这一点,请原谅我,但我会继续前进。 :)
首先,我想知道您的Column_Order
确实没有差距。因为如果没有间隙和值从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)
如果您有任何疑问,欢迎提出。