Criando tabelas através dos recursos de metadata do dbExpress no Delphi

Um dos recursos mais legais do dbExpress é a capacidade de criar tabelas, chaves primárias e chaves estrangeiras (foreign keys) através das classes do dbx metadata.

O código abaixo cria 2 tabelas: Country e State, adiciona chave primária em ambas as tabelas e um relacionamento (foreign key) entre as duas, tudo …

procedure CreateSchema(conn: TSQLConnection);
var
  Provider: TDBXDataExpressMetaDataProvider;
  Country, State: TDBXMetaDataTable;
  IdCountryField,
  IdField: TDBXInt32Column;
  StrField : TDBXUnicodeVarCharColumn;
begin
  Provider := DBXGetMetaProvider(conn.DBXConnection);

  // Country
  Writeln('Creating Table - Country ....................');
  Country := TDBXMetaDataTable.Create;
  Country.TableName := 'COUNTRY';

  IdCountryField := TDBXInt32Column.Create('COUNTRYID');
  IdCountryField.Nullable := false;
  IdCountryField.AutoIncrement := true;
  Country.AddColumn(IdCountryField);

  StrField := TDBXUnicodeVarCharColumn.Create('COUNTRYNAME', 50);
  StrField.Nullable := False;

  Country.AddColumn(StrField);

  Provider.CreateTable(Country);

  // Set COUNTRYID as Primary Key
  AddPrimaryKey(Provider, Country.TableName, IdCountryField.ColumnName);

  // Set Unique Index for COUNTRYNAME
  AddUniqueIndex(Provider, Country.TableName, StrField.ColumnName);

  // State
  Writeln('Creating Table - State ....................');
  State := TDBXMetaDataTable.Create;
  State.TableName := 'STATE';

  IdField := TDBXInt32Column.Create('STATEID');
  IdField.Nullable := false;
  IdField.AutoIncrement := true;
  State.AddColumn(IdField);

  StrField := TDBXUnicodeVarCharColumn.Create('SHORTNAME', 2);
  StrField.Nullable := False;
  State.AddColumn(StrField);

  StrField := TDBXUnicodeVarCharColumn.Create('STATENAME', 50);
  StrField.Nullable := False;
  State.AddColumn(StrField);

  State.AddColumn(IdCountryField);

  Provider.CreateTable(State);

  // Set STATEID as Primary Key
  AddPrimaryKey(Provider, State.TableName, idField.ColumnName);

  // Set Unique Index for STATENAME
  AddUniqueIndex(Provider, State.TableName, StrField.ColumnName);

  AddForeignKey(Provider, State.TableName, IdCountryField.ColumnName,
                Country.TableName, IdCountryField.ColumnName);

  FreeAndNil(Provider);
  FreeAndNil(Country);

end;

Download do código fontes completo aqui.

12 respostas
  1. Lucas
    Lucas says:

    Legal o artigo, mas fiquei com uma dúvida.

    Sempre vejo em programas como o IbExpert o “Prepared Statement” rodando antes da execução.

    Como faço isso com dbx e delphi?

    Responder
    • Andreano Lanusse
      Andreano Lanusse says:

      Quando sua aplicação precisa atualizar o schema da base de dados, mas o seu software suporta diferentes bancos de dados, com o metadata do dbexpress você não precisa saber como aplicar escrever o script, o dbexpress driver gera o script especifico para cada banco.

      Responder
  2. João
    João says:

    Obrigado pelo exemplo Andreano. Penso que ficou claro como criar uma tabela com “Provider.CreateTable(Country); “, no entanto isso é só parte da solução, pois se não existir um “Provider.AlterTable(Tabela, Campo);”, essa funcionalidade não serve de muito. A questão é: Como fazer um Alter Table com o metadata? Obrigado

    Responder
  3. Júlio César Ferreira (@jcmferreira)
    Júlio César Ferreira (@jcmferreira) says:

    Achei muito bom o recurso de METADATA com o Delphi, utilizando o dbExpress. Isso acaba com uma série de problemas com a interoperabilidade de bancos de dados diferentes.

    O recurso de criar chaves AutoIncrement é fantástico. Mas, no seu exemplo, via datasnap, é possível recuperar o novo código para o campo “STATEID” após uma inclusão via Client-Server?

    IdField := TDBXInt32Column.Create(‘STATEID’);
    IdField.Nullable := false;
    IdField.AutoIncrement := true;
    State.AddColumn(IdField);

    Responder
  4. Leo
    Leo says:

    Andreano, andei pesquisando e não consegui encontar nada a respeito de como retornar as colunas que são chaves primária de uma determinada tabela através dos recursos de MetaData.

    Com o MetaData é possível fazer isso?

    Responder
  5. Eric Serafim
    Eric Serafim says:

    Olá Andreano,

    Com relação a criação funciona muito bem, parabéns pelo exemplo, mas para alteração de tabela e coluna não consegui achar uma solução, tentei da forma abaixo mais recebe uma exceção.
    Estou utilizando a versão do XE, gostaria de receber um retorno a respeito.

    Abraço Eric Serafim

    TTabela = class(TDBXMetaDataTable)

    function TBancoDados.TTabela.AlterarTabela: Boolean;
    var
    metaProvider: TDBXDataExpressMetaDataProvider;
    sql: UnicodeString;
    begin
    metaProvider := nil;

    try
    try
    metaProvider := TDBXDataExpressMetaDataProvider.Create(FOwner.FConexao.DBXConnection);
    metaProvider.Open;

    sql := metaProvider.MakeAlterTableSql(Self.TableStorage, Self.ColumnsStorage); #1
    Result := FOwner.ExecutarScript(sql);
    Except
    raise;
    end;
    finally
    metaProvider.Free;
    end;
    end;

    #1 – FWriter.MakeSqlAlter(Builder, Table, Columns); #2

    #2 – procedure TDBXBaseMetaDataWriter.MakeSqlAlterTable(const Buffer: TDBXStringBuffer; const Table: TDBXTableRow; const Columns: TDBXTable);
    Original := Table.OriginalRow; //A exceção ocorre neste método (exception “Unsupported Operation”)

    Responder

Deixe uma resposta

Want to join the discussion?
Feel free to contribute!

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *


This site uses Akismet to reduce spam. Learn how your comment data is processed.