Fórum Framework DBX (Metadata) #408535

18/10/2011

0

Utilizando o Delphi XE com Firebird e MSSQL, decidimos embutir o script de criação e atualização do banco de dados no executável da aplicação, e frente a isso, fazer isso das classes DBX Metadata.

Acontece que não encontramos um modo de atualizar tabelas já existentes na base de dados, apenas criar novas. Nos testes que realizamos, o comando CreateTable do provider apenas (e realmente) cria a tabela, não conseguindo nós criar novas colunas em tabelas existentes.

Existe o comando AddColumn, mas este cria o vínculo da coluna apenas em memória, cabendo ao provider (TDBXMetadataProvider) aplicar essas atualizações ao BD.

Mas quando temos uma tabela já existente na base de dados, e precisamos adicionar uma nova coluna, índice, chaves, etc., temos que no final, aplicar essa atualização com o comando CreateTable, presente no provider, mas que é gerada uma exceção se a tabela já existe...

Precisaria de algo como ALTER TABLE, ou falando em método, algo como UpdateTable, para aplicar as mudanças.

Acreditem, já procuramos bastante, mas os exemplos demonstram apenas a criação do banco de dados, mas não apresentam a devida manutenção do dia-a-dia...

Penso que, se não há um modo de fazer isso, se ninguém faz essas atualizações COM O FRAMEWORK, de nada vale o recurso de metadata, se foge as situações reais e necessárias do dia-a-dia. O que acham?

Alguém utiliza DBX metadata no dia-a-dia? Alguém passou por isso, ou tem essa experência?

Obrigado!
Guess Me

Guess Me

Responder

Posts

18/10/2011

Gustavo Bretas

Olá, bom dia!

Eu ainda não tinha ouvido falar desse recurso no dbExpress!!

Mas sou adépto a enviar o script junto com o executável, na primeira vez que precisei, criei o mecanismo do zero!
Inicialmente foi desenvolvido para SQL Server, mas depois um amigo tbm precisou e adaptou para o Firebird.

Pode parecer estranho, mas ficou muito funcional, eu criei um Form, e cada script de versão fica em um Memo, mas como a query não suporta comitar todo o script, eu separo os blocos com o termo GO sozinho na linha, então uma função lê o que esta no Memo até encontrar o termo, comita e começa denovo.

No SQL Server vc tem a liberdade de fazer as verificações de existencia de tabela, colunas, etc, antes de enviar o comando para criar o objeto, então ficou tranquilo, já no Firebird vc não consegue fazer um IF e o comando junto, então ficou um pouco mais limitado, eu até pensei em desenvolver uma forma de fazer ele chegar usando Tags, mas o script de versão roda apenas uma vez e não tive tempo.

Aí vc vai questionar, mas vai chegar uma hora que vai ter dezenas de Memos no Form!! É verdade, nem tudo na vida são flores... rs! Eu deixava uma média de 15 scripts nele, os antigos deletava.
Até mesmo por que mantinha uma base atualizada para a implantação de novos clientes, então os scripts antigos ficaram apenas documentados, mas fora do executável.

Só pra finalizar, talvez haja maneiras melhores e mais eficientes, mas tbm uma coisa simples pode resolver seu problema, pensa ae! Abraço!
Responder

Gostei + 0

19/10/2011

Guess Me

Então, a algumas versões do delphi através, é possível fazer isso através do novo (que já não é tão novo assim) dbExpress.

Uma das vantagens mais interessantes, é o fato de podermos esquecer aquelas pequenas variações de nomenclaturas, e comandos de cada SGBD, pois o próprio recurso de metadata do DBX gerencia isso.

Algo como o parecido abaixo é possível ser feito:

Provider: TDBXDataExpressMetaDataProvider;
Table: TDBXMetaDataTable;
Id: TDBXInt32Column;
Text: TDBXUnicodeVarCharColumn;
begin
Provider := DBXGetMetaProvider(conn.DBXConnection);

Table := TDBXMetaDataTable.Create;
Table.TableName := TABLENAME;

Id := TDBXInt32Column.Create(TABLEID);
Id.Nullable := false;
Id.AutoIncrement := true;

Text := TDBXUnicodeVarCharColumn.Create(TABLETEXTFIELD, 40);
Text.Nullable := False;

Table.AddColumn(Id);
Table.AddColumn(Text);

Provider.CreateTable(Table); <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
AddPrimaryKey(Provider, Table.TableName, ...);


Extremamente útil, mas até agora na teoria, pois o nosso problema está exatamente na linha apontada... (<<<<<) Já tentamos fazê-lo funcionar com a tabela já existente, mas é gerada uma exceção...
Responder

Gostei + 0

19/10/2011

Guess Me

Alguém se habilita?
Responder

Gostei + 0

20/10/2011

Gustavo Bretas

Rapaz, eu estava olhando o código dessa classe aqui, realmente é bem complicado, estou achando mais fácil vc criar um compoente para fazer o que vc precisa do que usá-lo... rs!

Mas veja a classe TDBXMetaDataProvider tem o método MakeAlterTableSql, talvez ele te ajude.

Aqui no Delphi XE as units estão na pasta C:\Program FIles (x86)\Embarcadero\RAD Studio\8.0\Source\Database
Responder

Gostei + 0

27/10/2011

Vitor Rubio

Eu confesso que tentei e não descobri como é.

Deveria ser algo assim:


  provider.Execute(Provider.MakeAlterTableSql(Table.TableStorage, Table.ColumnsStorage));


como é feito no próprio método CreateTable, mas recebo a exception de unsuported operation. Simplesmente ele não faz nada quando é para alterar uma tabela adicionando um campo. Alguém tem alguma idéia?

Acho que para resolver isso não vai ter outra maneira, será necessário montar o script de alter table.
Responder

Gostei + 0

17/11/2011

Guess Me

Pois é, havíamos dado uma olhada no método MakeAlterTable, mas sem sucesso também.. seria uma melhor opção não utilizá-lo? Lamentável...
Responder

Gostei + 0

03/02/2012

Louremberg Almeida

essa função Provider.MakeAlterTableSql(Table.TableStorage, Table.ColumnsStorage)
apenas
altera o nome da tabela
altera visão
altera indice
altera chave estrangeira
mas não cria campo
por isso cria a exceção quando
mandamos utilizar essa função
Responder

Gostei + 0

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

Aceitar