Alteração do Banco de Dados Firebird?
Tenho um banco de dados com varias tabelas em meu cliente, onde ele esta continuamente cadastrando ou fazendo alterações, em mh casa, fiz varias modificações nas tabelas, criei novas tabelas, trigger, sp.
Qual é a maneira mais fácil pra eu atualizar esse bancos de dados?
Gerar um script das alterações?
Se for isso. como gerar um script tendo como resultado toda a diferença da estrutura de dois banco de dados?
Tenho que gerar um extract metadata?
Ou seja. mando comparar o banco que está no cliente e o banco que fiz as alterações (acrescentei tabelas, campos em tabalas que já existiam, trigges, etc) e recebo então um script com as linhas necessárias para deixar o banco que está no cliente igual ao banco que fiz as alterações.
O isql, faz isto tambem? Como utiliza-lo?
Sobre o isql ja achei aqui
Citação:
no diretorio do firebird na pasta bin, tem um utilitario isql.exe que permite vc rodar scripts SQL
faz assim:
cria um script sql por exemplo atualiza_cliente.sql com o seguinte conteudo:
e isso ai
Mais gostaria de saber se tem algum programa que faz isso sem ter que usar o isql.
Uso o IBExpert e Firebird 2.0
Qual é a maneira mais fácil pra eu atualizar esse bancos de dados?
Gerar um script das alterações?
Se for isso. como gerar um script tendo como resultado toda a diferença da estrutura de dois banco de dados?
Tenho que gerar um extract metadata?
Ou seja. mando comparar o banco que está no cliente e o banco que fiz as alterações (acrescentei tabelas, campos em tabalas que já existiam, trigges, etc) e recebo então um script com as linhas necessárias para deixar o banco que está no cliente igual ao banco que fiz as alterações.
O isql, faz isto tambem? Como utiliza-lo?
Sobre o isql ja achei aqui
Citação:
no diretorio do firebird na pasta bin, tem um utilitario isql.exe que permite vc rodar scripts SQL
faz assim:
cria um script sql por exemplo atualiza_cliente.sql com o seguinte conteudo:
ALTER TABLE NOME_DA_TABELA ADD DATA DATE;
depois vc pode executar o utilitario passando os parametros
isql -i atualiza_cliente.sql -q -user SYSDBA -pass masterkey
e isso ai
Mais gostaria de saber se tem algum programa que faz isso sem ter que usar o isql.
Uso o IBExpert e Firebird 2.0
Adriano_servitec
Curtidas 0
Respostas
Gandalf.nho
11/11/2007
Você pode montar um utilitário próprio usando um componente como o IBScript, da paleta IBX.
GOSTEI 0
Aldus
11/11/2007
Bom dia Adriano,
eu uso da seguinte forma, criei no meu banco uma tabela que grava quais arquivos sql já usei no sistema, sempre que quero alterar alguma coisa crio um arquivo sql.
Exemplo: SQL00343.SQL
Conteúdo: ALTER TABLE NOME_DA_TABELA ADD DATA DATE
Ao iniciar, verifico os sqls que estão no diretório da aplicação, que se ainda não tiver sido usado, executo-o através da função ExecuteDirect do sqlconnection.
Depois de executado com sucesso, gravo o nome do sql na tabela de atualizações.
Qualquer coisa, posta aí.
eu uso da seguinte forma, criei no meu banco uma tabela que grava quais arquivos sql já usei no sistema, sempre que quero alterar alguma coisa crio um arquivo sql.
Exemplo: SQL00343.SQL
Conteúdo: ALTER TABLE NOME_DA_TABELA ADD DATA DATE
Ao iniciar, verifico os sqls que estão no diretório da aplicação, que se ainda não tiver sido usado, executo-o através da função ExecuteDirect do sqlconnection.
Depois de executado com sucesso, gravo o nome do sql na tabela de atualizações.
Qualquer coisa, posta aí.
GOSTEI 0
Adriano_servitec
11/11/2007
Bom dia Adriano,
eu uso da seguinte forma, criei no meu banco uma tabela que grava quais arquivos sql já usei no sistema, sempre que quero alterar alguma coisa crio um arquivo sql.
Exemplo: SQL00343.SQL
Conteúdo: ALTER TABLE NOME_DA_TABELA ADD DATA DATE
Ao iniciar, verifico os sqls que estão no diretório da aplicação, que se ainda não tiver sido usado, executo-o através da função ExecuteDirect do sqlconnection.
Depois de executado com sucesso, gravo o nome do sql na tabela de atualizações.
Qualquer coisa, posta aí.
Desculpe a demora para responder, mais faz tempo que não mexia mais com programação, porém veio a duvida:Por exemplo, se eu criar um porjeto e distribuir para varios clientes, depois tenho que aumentar algum campo em alguma tabela, posso fazer usando via SQL assim:
alter table livros add chave char(1);
Correto?
Porém minha duvida é, pensando mais adiante, quando colocar esta nova estrutira da tabela para ser baixado, tem que atualizar nos clientes, então, a melhor forma é criar as tabelas em tempo de projeto no proprio sistema? E toda vez que atualizar algo o sistema recria as tabelas no cliente?
GOSTEI 0
Aldus
11/11/2007
Bom dia,
Não entendi bem sua pergunta, mas eu faço assim:
- Tenho um banco limpo apenas criado que coloco em novos clientes
- Tenho todos os scripts de criação de tabelas e indices em arquivo *.sql
- Quando inicio a aplicação verifico se algum desses arquivos, ou todos no caso de uma nova instalação, já foi usado pelo sistema. Caso não esteja na tabela onde guardo seus nomes, executo o seu conteudo através do .execute. Entao insiro o nome do arquivo na minha tabela de controle e pronto.
- Na proxima execucao, o sistema confrontará novamente a lista de arquivos SQL com a tabela que guardo seus nomes, se não houver nenhum arquivo novo, não executo nada e abro o sistema normalmente..
att
Não entendi bem sua pergunta, mas eu faço assim:
- Tenho um banco limpo apenas criado que coloco em novos clientes
- Tenho todos os scripts de criação de tabelas e indices em arquivo *.sql
- Quando inicio a aplicação verifico se algum desses arquivos, ou todos no caso de uma nova instalação, já foi usado pelo sistema. Caso não esteja na tabela onde guardo seus nomes, executo o seu conteudo através do .execute. Entao insiro o nome do arquivo na minha tabela de controle e pronto.
- Na proxima execucao, o sistema confrontará novamente a lista de arquivos SQL com a tabela que guardo seus nomes, se não houver nenhum arquivo novo, não executo nada e abro o sistema normalmente..
att
GOSTEI 0
Facc
11/11/2007
[b:ef09d74a95]aldus[/b:ef09d74a95],
Legal esse seu conceito, estou pensando em implementar em meus sistemas.
Mas tenho algumas dúvidas:
[list:ef09d74a95] Como vc faz para comparar o arquivo na pasta com o gravado no banco?[/list:u:ef09d74a95]
[list:ef09d74a95]Não se torna lenta fazendo essa verificação na inicialização?[/list:u:ef09d74a95]
[list:ef09d74a95]E se o usuário, por algum motivo, alterar a pasta onde estão os arquivos *.sql?[/list:u:ef09d74a95]
Legal esse seu conceito, estou pensando em implementar em meus sistemas.
Mas tenho algumas dúvidas:
[list:ef09d74a95] Como vc faz para comparar o arquivo na pasta com o gravado no banco?[/list:u:ef09d74a95]
[list:ef09d74a95]Não se torna lenta fazendo essa verificação na inicialização?[/list:u:ef09d74a95]
[list:ef09d74a95]E se o usuário, por algum motivo, alterar a pasta onde estão os arquivos *.sql?[/list:u:ef09d74a95]
GOSTEI 0
Aldus
11/11/2007
Segue a função AtualizaBanco que deve ser chamada ao iniciar o sistema:
Respondendo as suas dúvidas:
* Utilizo uma tabela chamada ´versoes´ para armazenar o nome do SQL incluído e executado.
1) Não se torna lenta fazendo essa verificação na inicialização?
* Note que depois de executar a instrução, eu deleto o SQL do disco
att
procedure AtualizaBanco; var TrsAB: Ttransactiondesc; SearchRec,SearchDir: TSearchRec; ArqSql,ListaArqSql: TStringList ; StrSql: string; op,QtdArq,RepetirLimpeza: integer; ContLoop,vPrimeiroArquivo,AchouVersoes: boolean; List: TStrings; begin ListaArqSql := TStringList.Create; AchouVersoes := False; List := TStringList.Create; try Dm.Conexao.GetTableNames(List); for op := 0 to List.Count - 1 do begin if LowerCase(List.Strings[op]) = ´versoes´ then AchouVersoes := True; end; finally List.Free; end; if not AchouVersoes then begin try TrsAB.TransactionID := 21; TrsAB.IsolationLevel := xilReadCommitted; dm.Conexao.StartTransaction(TrsAB); dm.conexao.ExecuteDirect(´create table versoes (´+ ´arquivosql varchar(50) not null , ´+ ´data date , ´+ ´hora varchar(5) character set WIN1252 collate WIN_PTBR , ´+ ´descricao varchar(70) character set WIN1252 collate WIN_PTBR , ´+ ´constraint ip_versoes primary key (arquivosql))´); dm.Conexao.Commit(TrsAB); dm.sql_versoes.CommandText := ´insert into versoes (arquivosql,data,hora) values (:arquivosql,:data,:hora)´; dm.sql_versoes.ParamByName(´arquivosql´).AsString := LowerCase(´sc_versoes.sql´); dm.sql_versoes.ParamByName(´data´).AsDate := StrToDate(FormatDateTime(´dd/mm/yyyy´,fMenu.DataSistema)); dm.sql_versoes.ParamByName(´hora´).AsString := FormatDateTime(´hh:nn´,Now); dm.sql_versoes.ExecSQL; except dm.Conexao.RollBack(TrsAB); end; end; if (FindFirst(´sql\sc*.sql´, faAnyFile, SearchRec) = 0) then begin repeat ListaArqSql.Add(SearchRec.Name); until (FindNext(SearchRec) <> 0); FindClose(SearchRec); ListaArqSql.Sort ; vPrimeiroArquivo := True; for QtdArq:=0 to ListaArqSql.Count-1 do begin op:=0; dm.cds_versoes.Close ; dm.sql_versoes.CommandText := ´select * from versoes where arquivosql=:arquivosql´ ; dm.sql_versoes.ParamByName(´arquivosql´).AsString := LowerCase(ListaArqSql[QtdArq]); dm.cds_versoes.Open ; if dm.cds_versoes.eof then begin try vPrimeiroArquivo := False; TrsAB.TransactionID := 22; TrsAB.IsolationLevel := xilReadCommitted; dm.Conexao.StartTransaction(TrsAB); ArqSql := TStringList.Create; ArqSql.LoadFromFile(´sql\´+ListaArqSql[QtdArq]); while op <= ArqSql.Count-1 do begin StrSql := ´´; ContLoop := True; while ContLoop do begin StrSql := StrSql + Trim(ArqSql.Strings[op]); if ((Right(Trim(ArqSql.Strings[op]),1) = ´;´) or (Trim(ArqSql.Strings[op])=´´)) then ContLoop := False else Inc(op); end; if StrSql <> ´´ then begin for RepetirLimpeza:=1 to 50 do begin StrSql := StringReplace(StrSql,´ ´,´ ´,[rfReplaceAll, rfIgnoreCase]); end; if UpperCase(strSql) <> ´COMMIT WORK;´ then dm.conexao.ExecuteDirect(StrSql); end; Inc(op); end; ArqSql.Free; dm.sql_versoes.CommandText := ´insert into versoes (arquivosql,data,hora) values (:arquivosql,:data,:hora)´; dm.sql_versoes.ParamByName(´arquivosql´).AsString := LowerCase(ListaArqSql[QtdArq]); dm.sql_versoes.ParamByName(´data´).AsDate := fMenu.DataSistema; dm.sql_versoes.ParamByName(´hora´).AsString := FormatDateTime(´hh:nn´,Now); dm.sql_versoes.ExecSQL; dm.Conexao.Commit(TrsAB); except ArqSql.Free; dm.Conexao.RollBack(TrsAB); // erro break; end; end; Deletefile(´sql\´+ListaArqSql[QtdArq]); end; end; end;
Respondendo as suas dúvidas:
* Utilizo uma tabela chamada ´versoes´ para armazenar o nome do SQL incluído e executado.
1) Não se torna lenta fazendo essa verificação na inicialização?
* Note que depois de executar a instrução, eu deleto o SQL do disco
att
GOSTEI 0
Adriano_servitec
11/11/2007
Muito obrigado aldus, respondeu minha pergunta, era esta mesmo a duvida.
Vou adaptar sua função a minha necessidade.
Valeu amigo.
Vou adaptar sua função a minha necessidade.
Valeu amigo.
GOSTEI 0
Anderson Witchs
11/11/2007
O right da linha é uma funcao propria sua ou do delphi?
if((Right(Trim(ArqSql.Strings[op]),1) = ;) or (Trim(ArqSql.Strings[op])=)) then
if((Right(Trim(ArqSql.Strings[op]),1) = ;) or (Trim(ArqSql.Strings[op])=)) then
GOSTEI 0