Reordear registros de uma tabela
Olá!
Tenho três tabelas relacionadas entre si: Artigos, Processos e Roteiro.
Cada artigo possui um roteiro de processos a ser seguido na produção. Esse roteiro deve ser seguido conforme o campo ORDEM_ROTEIRO. MAS essa sequência pode ser alterada pelo usuário e para que ele não precise ir registro por registro alterando o número da sequência, quero fazer um rotina no delphi ou no banco de dados(Trigger/Procedure) para automatizar esse processo. Exemplo 1: Tenho os registros com a sequência (1, 2, 3, 4, 5, 6, 7) ai deleto o registro cuja a ORDEM_ROTEIRO é 4 ai a sequência fica (1, 2, 3, 5, 6, 7), porém preciso que fique (1, 2, 3, 4, 5, 6)
Exemplo 2: Tenho os registros com a sequência (1, 2, 3, 4, 5, 6, 7) ai insiro um registro cuja a ORDEM_ROTEIRO deverá ser 3, ai a sequência fica (1, 2, 3, 3, 4, 5, 6, 7), porém preciso que fique (1, 2, 3, 4, 5, 6, 7, 8).
Se alguém tiver uma rotina que reordene essa listagem automaticamente ficarei muito grato. Desde já agradeço a ajuda.
Estou usando Delphi 7, DBExpress, Firebird 2.1.3.
Valeu.
Tenho três tabelas relacionadas entre si: Artigos, Processos e Roteiro.
Cada artigo possui um roteiro de processos a ser seguido na produção. Esse roteiro deve ser seguido conforme o campo ORDEM_ROTEIRO. MAS essa sequência pode ser alterada pelo usuário e para que ele não precise ir registro por registro alterando o número da sequência, quero fazer um rotina no delphi ou no banco de dados(Trigger/Procedure) para automatizar esse processo. Exemplo 1: Tenho os registros com a sequência (1, 2, 3, 4, 5, 6, 7) ai deleto o registro cuja a ORDEM_ROTEIRO é 4 ai a sequência fica (1, 2, 3, 5, 6, 7), porém preciso que fique (1, 2, 3, 4, 5, 6)
Exemplo 2: Tenho os registros com a sequência (1, 2, 3, 4, 5, 6, 7) ai insiro um registro cuja a ORDEM_ROTEIRO deverá ser 3, ai a sequência fica (1, 2, 3, 3, 4, 5, 6, 7), porém preciso que fique (1, 2, 3, 4, 5, 6, 7, 8).
Se alguém tiver uma rotina que reordene essa listagem automaticamente ficarei muito grato. Desde já agradeço a ajuda.
Estou usando Delphi 7, DBExpress, Firebird 2.1.3.
Valeu.
Carlos Heidrich
Curtidas 0
Respostas
Wilson Junior
30/07/2010
Exemplo 1
Exemplo 2
Antes de gravar o novo registro de ordem 3, faça:
Lembrando, abra uma transação para Apagar e depois efetuar o UPDATE e o mesmo para gravar.
Exemplo:
Espero ter colaborado.
UPDATE ORDEM_ROTEIRO SET Ordem = Ordem - 1 WHERE Ordem > 4
Exemplo 2
Antes de gravar o novo registro de ordem 3, faça:
UPDATE ORDEM_ROTEIRO SET Ordem = Ordem + 1 WHERE Ordem >= 3
Lembrando, abra uma transação para Apagar e depois efetuar o UPDATE e o mesmo para gravar.
Exemplo:
try
Inicia_Transacao;
ApagaRegistro_4;
ExecutaUpdateRegistro_4;
Grava_Transacao;
except
Cancela_Transacao;
raise;
end;
try
Inicia_Transacao;
ExecutaUpdateRegistro_3;
GravaRegistro_3;
Grava_Transacao;
except
Cancela_Transacao;
raise;
end;
Espero ter colaborado.
GOSTEI 0
Carlos Heidrich
30/07/2010
Wilson... Valeu pela dica, me ajudou a ter algumas ideias, mas ainda não foi o suficiente. Tentei fazer por uma trigger o primeiro exemplo mas não tive sucesso, visto que sempre entrava em loop infinito na trigger.
Existe um método de ordenação que os professores ensinam para situações como essa, mas agora não me recordo como se faz(já faz um tempinho que tranquei a faculdade) . O método possui uns 3 ou 4 ou (não lembro direito). Se alguém puder me citar exemplos de ordenação desses que se ve nas faculdades, ou qualquer outra forma de resolver essa questão, eu agradeço. Lembrando que é possivel alterar a sequência de um item ou até mesmo deletar um item da lista sendo nessesário a reordenação após as alterações.
Existe um método de ordenação que os professores ensinam para situações como essa, mas agora não me recordo como se faz(já faz um tempinho que tranquei a faculdade) . O método possui uns 3 ou 4
for
while
GOSTEI 0
Eriley Barbosa
30/07/2010
Vamos começar pelo deletar um item da sua lista.
No evento AfterDelete do seu ClientDataset, digite:
begin
if not(SeuClientDataset.IsEmpty) then
begin
SeuClientDataset.DisableControls;
While not(SeuClientDataset.Eof) do
begin
SeuClientDataset.Edit;
SeuClientDataset.FieldByName('ordem').Value := SeuClientDataset.FieldByName('ordem').Value - 1;
SeuClientDataset.Post;
SeuClientDataset.Next;
end;
SeuClientDataset.ApplyUpdates(0);
SeuClientDataset.EnableControls;
end;
Declare OrdemIns como sendo do tipo Integer na seção Private da unit onde está seu clientDataset.
Vamos agora a inserção, no evento BeforeInsert do seu clientDataset digite:
begin
if not(SeuClientDataset.IsEmpty) then
begin
SeuClientDataset.DisableControls;
SeuClientDataset.Last;
OrdemIns := SeuClientDataset.FieldByName('ordem').Value;
SeuClientDataset.EnableControls;
end;
end;
No evento BeforePost do seu clientDataset digite:
begin
if SeuClientDataset.Locate('Ordem', SeuClientDataset.FieldByName('ordem').Value, []) then
SeuClientDataset.FieldByName('ordem').Value := OrdemIns;
end;
Atenciosamente
Eriley
GOSTEI 0
Carlos Heidrich
30/07/2010
OláEriley, a sua rotina de deletação ficou perfeita , porém a de inserção entrou em loop infinito por causa do Locate no BeforePost(Acredito eu). Se puderes dar mais uma ajuda, inclusive na rotina de update, agradeço muito. Valeu...
GOSTEI 0
Eriley Barbosa
30/07/2010
Não é o Locate e sim o Last no Before Insert, tente assim:
Declare OrdemIns como sendo do tipo Integer na seção Private da unit onde está seu clientDataset.
Vamos agora a inserção, no evento BeforeInsert do seu clientDataset digite:
var
Qry: TSQLQuery;
begin
if not(SeuClientDataset.IsEmpty) then
begin
Qry := TSQLQuery.Create(nil); {: cria uma instância do objeto}
try
Qry.SQLConnection := SeuSQLConnection;
Qry.SQL.Add('SELECT ORDEM_ROTEIRO FROM ROTEIRO WHERE COD_ARTIGO = ' +
SeuClientDataset.FieldByName('COD_ARTIGO').AsString
' AND COD_PROCESSO = ' + SeuClientDataset.FieldByName('COD_PROCESSO').AsString + ')';
Qry.Open;
if not(Qry.Fields[0].IsNull) then
OrdemIns := Qry.Fields[0].AsInteger;
finally
FreeAndNil(Qry); {: libera o objeto da memória}
end;
end;
end; Quanto ao Update, explique melhor.
Qry: TSQLQuery;
begin
if not(SeuClientDataset.IsEmpty) then
begin
Qry := TSQLQuery.Create(nil); {: cria uma instância do objeto}
try
Qry.SQLConnection := SeuSQLConnection;
Qry.SQL.Add('SELECT ORDEM_ROTEIRO FROM ROTEIRO WHERE COD_ARTIGO = ' +
SeuClientDataset.FieldByName('COD_ARTIGO').AsString
' AND COD_PROCESSO = ' + SeuClientDataset.FieldByName('COD_PROCESSO').AsString + ')';
Qry.Open;
if not(Qry.Fields[0].IsNull) then
OrdemIns := Qry.Fields[0].AsInteger;
finally
FreeAndNil(Qry); {: libera o objeto da memória}
end;
end;
end; Quanto ao Update, explique melhor.
GOSTEI 0