Fórum Atualização de banco de dados automático #361336

18/07/2008

0

Olá pessoal, preciso de uma dicas de vocês, estou implementando a atualização do banco de dados de forma automática, a atualização da aplicação ja consegui fazer. Tenho as seguintes dúvidas:

1) Controlo o banco de dados por versão? e comparo a versão mínima exigido para aplicativo e faço os comandos de cada versão?

2) Ou mando executar todos os comandos e se der erro é que já existe essa alteração no banco? tipo mando fazer um update em uma tabela se retornar erro quer dizer que já foi feito.

Se alguém tiver dicas por favor mande...

Obrigado


Altingon

Altingon

Responder

Posts

18/07/2008

Mazzi

idem... se alguem puder ajudar.. estou no mesmo dilema


Responder

Gostei + 0

18/07/2008

Catunda

Não seria suficiente verificar se a tabela ou os campos já existem?
Pois imagino que essa atualização não seja com respeito a mudar valor de dados e sim mudar a estrutura do banco.

Utilize GetTableNames() e GetFieldNames(). É assim que eu faço.
Se a tabela ou campo não existe executa-se a atualização, caso contrario nada acontece.


Responder

Gostei + 0

21/07/2008

Mazzi

e qto ao tipo do atributo? (Integer, varchar, etc...?) tem como testar tbm?


Responder

Gostei + 0

21/07/2008

Fabianosales

Você pode testar o tipo de dados usando os TFields de um dataset qualquer. Tipo... faz um select que não retorne nenhum dado e você terá toda os metadados todos mapeados para ´MyDataSet.Fields´.


Responder

Gostei + 0

22/07/2008

Catunda

tabela.fieldbyname(campo).datatype retorna o tipo do campo
tabela.fieldbyname(campo).size retorna o tamanho do campo


Responder

Gostei + 0

22/07/2008

Vitor Alcantara

No meu programa eu tenho uma tabela com a seguinte configuração

TAB_VERSAO
(
OBJETO VARCHAR(100),
VERSAO INT,
DESCRICAO VARCHAR(255)
)
;

E tenho uma unit onde guardo a o nome do objeto e a versao, do mesmo, em um array de um objeto com as caracteristicas acima, dai na inicialização do programa pecorro esse array e verifico a versão com a versão do banco, caso aja alguma modificação executo uma query (no meu caso como uso os componentes da palheta Interbase uso um IbScript), com a seguinte nomenclatura NOME_DO_OBJETO_VERSAO (Ex: PRODUTO_2), dessa forma posso alterar não somente a estrutura dos campos/fields, como também posso criar novos indices, alterar procedures, triggers.....


tTabelas = Class
  strict private
    FVersao: Integer;
    FDescricao: String;
    FTabela: String;
    procedure SetDescricao(const Value: String);
    procedure SetTabela(const Value: String);
    procedure SetVersao(const Value: Integer);
  public
    property Tabela :String read FTabela write SetTabela;
    property Versao :integer read FVersao write SetVersao;
    property Descricao:String read FDescricao write SetDescricao;
  End;


tAtualizaTabela = class
  private
  public
    Tabelas : Array of tTabelas;
    Conexao : tConexao;
    
    Dm      : tDmAtualizaTab;
    destructor Destroy;
    constructor Create;

    function Verifica:Integer;
    function AtualizaTabela(Nome:String;VersaoAtual,VersaoNova:Integer):Integer;
  end;



constructor tAtualizaTabela.Create;
var
  I: Integer;
begin
  
  Conexao := tConexao.create(nil);
  Dm := TDmAtualizaTab.Create(nil);
  
    
  SetLength(Tabelas , 46);//46 é a quantidade de tabelas que tenho no meu banco.

  Tabelas[0] := tTabelas.Create;
  with Tabelas[0] do
  begin
    Versao := 1;//Versão atual do objeto
    Tabela := ´APT´;//Nome do objeto
    Descricao := ´´;//A descrição
  end;

  Tabelas[1] := tTabelas.Create;
  with Tabelas[1] do
  begin
    Versao := 1;
    Tabela := ´APT_CAT´;
    Descricao := ´´;
  end;

  Tabelas[2] := tTabelas.Create;
  with Tabelas[2] do
  begin
    Versao := 3;
    Tabela := ´EMP´;
    Descricao := ´´;
  end;
   //Daqui pra baixo coloco o restante das tabelas e outros objetos do meu banco.
end;



Exemplo do ibScript EMP_3 que está contido no meu datamódule

ALTER TABLE EMP
ADD EMP_REST_CODEST  INT DEFAULT 1,
ADD EMP_REST_CODCENTRO INT DEFAULT 1,
ADD EMP_REST_COMISSAO DECIMAL(10,2) DEFAULT 0 NOT NULL,
ADD EMP_REST_CODCONTAAPT INT,
ADD EMP_RECE_CODEST INT DEFAULT 2,
ADD EMP_RECE_CODCENTRO INT DEFAULT 2,
ADD EMP_RECE_COMISSAO DECIMAL(10,2) DEFAULT 0 NOT NULL;

UPDATE TAB_VERSAO
SET VERSAO = 3
WHERE OBJETO = ´TAB_VERSAO´;



function tAtualizaTabela.Verifica: Integer;
var
  I: Integer;
begin
  try
    if not Conexao.Trans.InTransaction then
    begin
      Conexao.Trans.StartTransaction;
    end;


    for I := 0 to Length(TAbelas)-1 do
    begin
      with Conexao.Query do
      begin
        Close;
        SQL.Clear;
        SQL.Add(´SELECT * FROM TAB_VERSAO WHERE OBJETO = ´+QuotedStr(Tabelas[I].Tabela));
        Open;

        if RecordCount > 0 then
        begin
          if FieldByName(´VERSAO´).AsInteger < Tabelas[I].Versao  then
          begin
            AtualizaTabela(Tabelas[I].Tabela , FieldByName(´VERSAO´).AsInteger , Tabelas[I].Versao );
          end;
        end;
      end;
    end;

    if Conexao.Trans.InTransaction then
    begin
      Conexao.Trans.Commit;
    end;

    Result := 0;

  except
    on E: Exception do
    begin
      Result := -1;
      if Conexao.Trans.InTransaction then
      begin
        Conexao.Trans.Rollback;
      end;
      raise Exception.Create(e.Message);
    end;
  end;
end;


function tAtualizaTabela.AtualizaTabela(Nome: String; VersaoAtual,
  VersaoNova: Integer): Integer;
var
  I:INteger;
begin
  Try
    for I := VersaoAtual +1 to VersaoNova do
    begin
      with Dm do
      begin
        with TIBScript(FindComponent(Nome+´_´+IntToStr(I))) do
        begin
          ExecuteScript;
        end;
      end;
    end;
  Except
    On E : Exception do
    begin
      Result := -1;
      raise Exception.Create(e.Message);
    end;

  End;

end;


Onde conexão é uma classe que contem os objetos de conexão com o banco de dados (IbTransaction=Trans , IbDataBase=Banco),
Onde DmAtualizaTab é o DataModule onde guardo os IbScripts com as alterações no banco.

É um pouco trabalhoso pois no começo pois se tem que declarar todo os objetos do banco de dados no procedimento ´[b:396def9972]constructor tAtualizaTabela.Create;´[/b:396def9972], mais depois de feito (pelo menos pra mim) ficou mais fácil de se fazer alterações no banco de dados.

Dai cada vez que tenho de alterar algum objeto do banco de dados, vou na unit altero a versão do objeto (no procedimento Create da classe AtualizaTabela), e crio o ibScript no datamodule com a seguinte nomenclatura ´NomedoObjeto_Versao´.

É apenas uma idéia, mais tem funcionado bem comigo.


Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar