2011-02-03 1 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

ответ

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

Спасибо, что получилось лучше. Я ценю все сообщения. –

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. –

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 заявления должно существовать в большинстве основной СУБД.

Примечание: есть ошибка (запаса) TADOQuery, которая не будет устанавливать параметр all 4 :order параметров за один раз. 4 потребуются все значения с одинаковым значением, если только СУБД не будет оптимизировать запрос для конкретной СУБД.

+0

Вы считаете, что 'column_order' a) является числовым, и b) не имеет пробелов в своей последовательности. Должны ли эти предположения? Вы можете исправить свой код, используя «ROW_NUMBER() OVER (ORDER BY column_order)» или эквивалент, а затем примените свою логику к результирующему столбцу. – onedaywhen

+0

@one - есть комментарий о ожидании СУБД. Вопрос предполагает, что пробелов нет, но ОП может прояснить, если это неверно. – RichardTheKiwi

+0

«Вопрос предполагает, что нет пробелов» - где он говорит это? То же, что тип данных является целым (или числовым). – onedaywhen

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) 

Если у вас есть какие-либо вопросы, они приветствуются.

 Смежные вопросы

  • Нет связанных вопросов^_^