2011-02-03 31 views
0

我有一個數據庫表名爲P_Columns。此表包含列ADOQuery,SQL語句和數據庫中行的重新排序

ID 
Column_Name 
Column_Type 
Column_Visible 
Column_Order 

此數據表由顯示dbgrid的應用程序填充和更新。 此應用程序有一個按鈕。當點擊它時,它會佔用選定的行。並將其向上移動一行(這是我需要幫助的地方)。

現在我的初始SQL語句(SELECT * FROM P_Columns Order by Column_Order asc)設置正確的順序。原來。

我需要找出是否有更新的Sql語句,這將允許我交換所選記錄的Column_Order。與之前的紀錄相比。

希望這是有道理的。

+0

這是連接到哪個dbms? – RichardTheKiwi 2011-02-03 03:02:39

回答

0

這裏是Delphi代碼,它使用TADOCommand來調用兩次更新語句。這是針對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; 
0

我相信這會爲你做它...

update P_Columns 
set Column_Order = ((select count(*) from P_Columns) + 1) - Column_Order 
+0

我在這裏做的是記錄的計數,增加1,然後減去當前的Column_Order ...所以Column_Order列以1,2,3 ... 5開始並且變爲5,4, 3 ... 1。 – 2011-02-03 03:03:41

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存在。

注意:(庫存)TADOQuery中存在一個錯誤,它不會一次性設置參數全部4 :order參數。除非已知DBMS優化針對特定DBMS的查詢,否則將需要4個參數都帶有相同的值。

+0

您假設`column_order` a)是數字,並且b)在其序列中沒有空位。這些假設是否到期?你可以通過使用`ROW_NUMBER()OVER(ORDER BY column_order)`或者等價的方法修復你的代碼,然後將你的邏輯應用到結果列中。 – onedaywhen 2011-02-03 10:00:39

+0

@one - 有關於DBMS掛起的評論。問題表明沒有差距,但是OP可以澄清這是否是不真實的。 – RichardTheKiwi 2011-02-03 10:04:44

0

我可能是錯的,但它似乎在這種情況下,你不必有一個聲明唯一的解決方案。我也沒有看到它的含義,因爲你只是在談論更新聲明,這並不意味着你不能有任何其他語句準備你的更新,是嗎?但如果你確實有這個想法,請原諒我,但我會繼續前進。 :)

首先,我想知道你的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) 

如果您有任何疑問,歡迎他們。