Utilizando o dbExpress (DBX) Framework em Delphi 2010

Tenho recebido muitas perguntas sobre como utilizar do dbExpress Framework para efetuar operações no banco de dados, então resolvi postar este exemplo de uma aplicação console, o exemplo é bem fácil de entender e mostra as opções básicas de conexão, transação e query.

Pretende em futuros posts, explicar mais sobre o framework.

program DBX4Example;
{$APPTYPE CONSOLE}

uses SysUtils, DBXDynalink, Dialogs, DbxInterBaseReadOnlyMetadata, DBXCommon;

var

  aConnName: string;
  aDBXConn: TDBXConnection;
  aDBXTrans: TDBXTransaction;
  aCmnd: TDBXCommand;
  aReader: TDBXReader;
  aColCount: integer;

begin

  aDBXConn := TDBXConnectionFactory.GetConnectionFactory.GetConnection
    ('EMPLOYEE IB', 'sysdba', 'masterkey');

  if aDBXConn <> nil then
  begin

    // Write the all connection parameters
    Writeln('================= Connection Properties ============');
    Writeln(aDBXConn.ConnectionProperties.Properties.Text);
    Writeln('====================================================');
    Writeln('');

    aCmnd := aDBXConn.CreateCommand;

    // Start transaction
    aDBXTrans := aDBXConn.BeginTransaction(TDBXIsolations.ReadCommitted);

    // Prepare and execute the SQL Statement
    aCmnd.Text := 'SELECT * FROM Country';
    aCmnd.Prepare;
    aReader := aCmnd.ExecuteQuery;

    aColCount := aReader.ColumnCount;
    Writeln('Results from Query: ' + aCmnd.Text);
    Writeln('Number of Columns:  ' + IntToStr(aColCount));

    while aReader.Next do
    begin
      Writeln(aReader.Value['Country'].GetAnsiString);
    end;

    Writeln('====================================================');
    Writeln('');

    // Commit transaction
    aDBXConn.CommitFreeAndNil(aDBXTrans);

    Readln;
    aReader.Free;
    aCmnd.Free;
    aDBXConn.Free;

  end;

end.
35 respostas
  1. isaque Pinheiro
    isaque Pinheiro says:

    Blz Andreano ? Uso muito esse tipo de código hj em todos os meus projetos, inclusive criei uma class onde posso usa-la de qualquer ponto do meus códigos, assim eliminei MUITOS componentes visuais que serviam só para pesquisa, e pequenos loops.
    Espero o dia em que irei criar esse código (instanciar esses objetos de conexão) e a IDE poderá encherga-los se a Unit onde criei estiver no “uses”, quem sabe isso não ta proximo ? rsrsrs
    Muito legal o uso do dbExpress Framework.

    Responder
  2. Laercio Guerço
    Laercio Guerço says:

    Este exemplo é uma tendência, ou ainda, para os que preferem como eu, usar componentes para estabelecer conexão e tudo que o Mapeamento Objeto Relacional requer e a combinação SQLConnection + DataSetProvider + ClientDataSet é o caminho?

    Espero que a resposta seja simplesmente “Sim”.

    Responder
  3. Maicon
    Maicon says:

    Quando arrasto a conexao para o DM da um erro gigante, segue o inicio dele:

    See the end of this message for details on invoking
    just-in-time (JIT) debugging instead of this dialog box.

    ************** Exception Text **************
    System.NullReferenceException: Object reference not set to an instance of an object.
    at Borland.Data.Explorer.DataExplorerIDEImpl.CreateDBXConnection(TreeNode aNode)
    at Borland.Data.Explorer.DataExplorerIDEImpl.DragDrop(Object Sender, ItemDragEventArgs Event)
    at Borland.Data.Explorer.DataExplorerControl.a(Object , ItemDragEventArgs )
    at System.Windows.Forms.TreeView.OnItemDrag(ItemDragEventArgs e)
    at System.Windows.Forms.TreeView.TvnBeginDrag(MouseButtons buttons, NMTREEVIEW* nmtv)
    at System.Windows.Forms.TreeView.WmNotify(Message& m)
    at System.Windows.Forms.TreeView.WndProc(Message& m)
    at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
    at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
    at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

    Responder
  4. Carlos Eduardo
    Carlos Eduardo says:

    Olá Andreano, gostaria de saber como faço para controla várias transações com o DBX4? exemplo. aDBXTrans1, aDBXTrans2 etc, tenho que criar vários objetos? é isso? poderia me dar um exemplo por favor?

    Responder
  5. Delmar Wichnieksi
    Delmar Wichnieksi says:

    Colegas Delphianos

    Multiplas transações em uma única conexão com DBExpress 4.0 e novos comandos de transações, é possível?

    Gostaria de saber se o DBExpress do Delphi 2010 (DBExpress 4.0) através do uso dos métodos:

    function BeginTransaction: TDBXTransaction; overload;
    function BeginTransaction(Isolation: TDBXIsolation): TDBXTransaction; overload;

    procedure CommitFreeAndNil(var Transaction: TDBXTransaction);

    procedure RollbackFreeAndNil(var Transaction: TDBXTransaction);
    procedure RollbackIncompleteFreeAndNil(var Transaction: TDBXTransaction);

    do SqlConnection já suporta multiplas transações em uma única conexão?

    Em um curso de DataSnap do do Renato Matos (site istudar) ele mostrou com os métodos deprecados (DBExpress 3.0) que uma única conexão não sabe trabalhar com multiplas transações. Para resolver ele criou várias conexões. Mas eu esperava algo muito mais poderoso do DBExpress, trabalhar com várias transações em um única conexão.

    Se isto ainda não é possível (pelo menos não ao meu pequeno conhecimento de DBExpress, sempre usei a dobradinha Firebird e IBO) fica a dica para os arquitetos da Embarcadero fazer com que seja possível trabalhar com várias transações em uma única conexão. Na minha visão conexão deve ser apenas um canal de comunicação entre o App Server e o DB para levar as intruções/statements. E transação deve um mecanismo independente da conexão.

    Eu tentei criar métodos no server para retornar uma transação (TDBXTransaction) ao proxi do cliente, na expectativa de que eu pudesse passar para o CommitFreeAndNil e o RollbackFreeAndNil a transação que aquele cliente criou, numa tentativa de que as transações, mesmo usando uma única conexão do server ao DB, soubessem se individualizar sobre suas operação de inserção, deleção, update, ou seja, a transação de um cliente não deveria interferir na transação de outro cliente.

    Código do App Server e invocado no proxi do cliente (o cliente guardaria a transação dele para devolver ao servidor a mesma transação na hora de chamar o Commit ou RollBack)
    ….
    class function Start: TDBXTransaction;
    class procedure Commit(Tran: TDBXTransaction);
    class procedure RollBack(Tran: TDBXTransaction);
    …..

    class function TUtil.Start: TDBXTransaction;
    begin
    Result := getConn.BeginTransaction;
    end;

    class procedure TUtil.Commit(Tran: TDBXTransaction);
    begin
    getConn.CommitFreeAndNil(Tran);
    end;

    class procedure TUtil.RollBack(Tran: TDBXTransaction);
    begin
    getConn.RollbackFreeAndNil(Tran);
    end;

    mas aí estes métodos não apareceram na classe proxi, suponho que seja pelo fato de que ainda não é possível transferir entre client/server um tipo TDBXTransaction. O que também poderia ser feito, talvez.

    É isto aí, aguardo comentários se isto é possível. Caso contrário, aguardamos as novidades pela Embarcadero.

    Delmar
    Ajuricaba/Ijuí -RS

    Responder
  6. Paulo
    Paulo says:

    Estou tendo um problema depois que migrei para a dbExpress Framework do Delphi 2010 e não achei solução. A situação é a seguinte: As vezes preciso recriar uma procedure do Firebird pela aplicação, na primeira vez que executo o “create alter procedure…” funciona perfeitamente DBConnection.ExecuteDirect(SqlProcedure) e se logo em seguida eu tentar recria-la novamente, e gerado o erro: lock conflict on no wait transaction unsuccessful metadata update object NOME_PROCEDURE is in use, lembrando que na framework anterior ela não ficava em uso, eu conseguia fazer esta operação, não existe outro usuario conectato ao banco e ainda não foi executado nenhuma query utilizando a procedure. Você tem alguma ideia do que pode ser? Eu estou fazendo alguma coisa errado ou esta framework não suporta este tipo de operação!

    Responder
  7. Andreano Lanusse
    Andreano Lanusse says:

    Oi Paulo, isso acontece porque a transação em que foi executa a criação ainda está aberta e desta forma e o firebird não conseque atualizar o metadata da mesma.

    Faça um commit antes de recriar. Isso não é problema do dbExpress e sim de como você implementou.

    Responder
  8. Francisco Taveras
    Francisco Taveras says:

    Saludos Andreano, mi problema es que en mi proyecto instancia diferentes clases (Datamodules) para que desea manejar con una única transacción (TFdsPersonas, TFdsContactos), como los componentes en de datos en esos datamodules se le asigna un sqlConnection que se crea con el servidor (ServerContainer) cada cliente comparte la misma conexion y quiero saber como separar las conexiones por sesiones.

    Gracias.

    Responder
  9. Rafael
    Rafael says:

    Bom dia brother, bom sou iniciante e queria usar o dbexpress mas ele não tem aba no meu delphi 2010, tem como instalar ou abilitar ela ..?
    desde ja agradeco, brigado pela ajuda..

    Responder
  10. Andreano Lanusse
    Andreano Lanusse says:

    Francisco, puedes trabajar de dos maneras distintas. Una utilizar el pool de conexión de dbExpress y no si preocupar con cual conexión pasar y la otra tener un Data Module para la conexión donde su ServerClass.LifeCyle será Session.

    Responder
  11. Leandro
    Leandro says:

    Andreano, estou estudando essa forma de trabalho, podemos ate eliminar o SqlConnection, podemos ter varias transações…. em fim algo novo tenho uma duvida não “custa” muito criar uma conexao executar alguns sql e depois destruir ela ?
    ou seria melhor gerar uma conexao e sempre usar ela ? so que ai nao podemos ter mais de uma transacao aberta certo ?

    Abraços Leandro.

    Responder
  12. Leandro
    Leandro says:

    Estou migrando meus componentes mais em algum momento ainda é necessario usar um TDataset por um acaso tem como converter um TDBXReader em um TDataSet vi que dava de fazer isso para um ClienteDataSet me ajudaria tambem um TClienteDataSet para TDataSet.

    Responder
  13. Francisco Taveras
    Francisco Taveras says:

    Gracias por la respuesta anterior, sobre el manejo de transacciones en el servidor Datasnap, ya tengo la solución utilizando un Data Module por sesión, pero me seria de mucha utilidad algún ejemplo donde se usa pool en un servidor de capa intermedia para manejar transacciones.

    Gracias.

    Responder
  14. Jovany
    Jovany says:

    Ola Andreano Lanusse:

    Tenho a mesma duvida do meu delphi é original devo reinstalar novamente? aparece essa mensagem: Unable to find dbExpress Configuration files

    Rafael disse:
    9 de abril de 2010 às 20:28

    Bom dia brother, bom sou iniciante e queria usar o dbexpress mas ele não tem aba no meu delphi 2010, tem como instalar ou abilitar ela ..?
    desde ja agradeco, brigado pela ajuda..

    Responder
  15. Rafael
    Rafael says:

    Olá Andreano:

    Gostaria de saber como usar parametros num comando SQL:
    aCmnd.Text := ‘SELECT * FROM Country where cod = :cod’, pois até agora procurei em vários locais e ainda não achei uma solução.
    Obrigado

    Responder
  16. Carlos Gonzaga
    Carlos Gonzaga says:

    Oi Andreano
    Tabém faço a mesma pergunta do nossso amigo Rafael, em relação ao uso de consultas parametrizadas, pois até no help q acompanha a ferramenta não diz nada,,,, só mostra propriedades/metodos .. (CreateParameters,Addparameter) !

    Responder
  17. Marcio Cruz
    Marcio Cruz says:

    Boa tarde Andreano!
    Estou tentado fazer um master/detail no Delphi 2010 e está me apresendo o seguinte erro: “Cannot load metadata for datasnap.Add driver unit to your use (DBXInterbase or DBXDB2 or DBXOracle…..) quando eu escolho no SQLDataSet na propriedade CommandType ponho ctStoredProc e clico na propriedade CommandText para selecionar o nome do storedProcedure dá esse erro. O que será isso 🙂 Abraço

    Responder
    • Andreano Lanusse
      Andreano Lanusse says:

      Olá Marcio,

      A mensagem está dizendo, declare a unit referente ao seu banco de dados, DBXInterbase, DBXDB2 ou DBXOracle. esta é a unit referente ao driver do banco que você está usando.

      Responder
  18. Cleyton
    Cleyton says:

    Boa tarde…
    Seguinte, eu já tentei desinstalar e reinstalar o delphi 2010 várias vezes (inclusive já baixei novamente de outra fonte) e não adiantou nada…
    Eu estou c/ o mesmo problema do Jovany, no DataExplorer aparece essa msg: “Unable to find dbExpress Configuration files”, ou seja, não consigo fazer conexão c/ nenhum banco de dados através do delphi.
    Alguém sabe o q devo fazer?
    Grato…

    Responder
  19. Rafael
    Rafael says:

    Olá Andreano muito prazer,

    Gostaria de saber porque neste exemplo você adicionou Dialogs no uses?

    Pergunto porque observei que esse exemplo funciona perfeitamente com Firebird sem a unit Dialogs no uses, porém, com MSSQL 2008 simplesmente não funciona.

    PS.: Testei exaustivamente o código abaixo com combinações entre Delphi 2010, XE, MSSQL Server 2008 e 2008 R2, windows x86 e x64.
    Se tirar a unit Dialogs no uses a conexão não funciona. Seria um bug?

    Program TesteDBX;
    {$APPTYPE CONSOLE}

    uses
    SysUtils, DBXCommon, DbxMsSql, Dialogs;

    var
    Conn: TDBXConnection;
    begin
    try
    Conn := TDBXConnectionFactory.GetConnectionFactory.GetConnection(‘APP’, ‘sa’, ‘sa’);
    if Conn nil then
    writeln(‘ok’);

    readln;
    except
    on E: Exception do begin
    Writeln(E.ClassName, ‘: ‘, E.Message);
    readln;
    end;
    end;
    end.

    Agradeço a atenção,

    Responder
    • Andreano Lanusse
      Andreano Lanusse says:

      @Rafael,

      Em algum momento usei showmessage durante o desenvolvimento do exemplo e esqueci de retirar. O fato de não funcionar com SQL Server 2008 é porque a unit DbxMSSQLReadOnlyMetadata não foi declarada, cada banco tem sua unit para leitura do metadata

      Responder
  20. Rafael
    Rafael says:

    @Andreano,

    Sinto muito usar esse espaço para isso e sinto muito também lhe contrariar, mas infelizmente essa não é a solução.

    Adicionei todas as units que iniciam com DBXMSSQL e sempre dá o mesmo erro:
    “Client library may be missing, not installed properly, of the wrong version, or the driver may be missing from the system path.”

    Veja que o código que mandei se resume a apenas tentar uma conexão com o banco.
    Veja também que estou afirmando que basta adicionar a unit Dialogs para que tudo funcione bem.
    E isso significa que minha configuração está correta, embora isso seja bem esquisito.

    Aprecio muito sua ajuda, abs.

    Responder
  21. Paulo Lima Jr
    Paulo Lima Jr says:

    Olá Andreano,
    Uso esse exemplo a algum tempo, mas no decorrer da aplicação que trabalha com banco Mysql, precisei adicionar alguns campos do tipo Blob e TinyText para imagens e textos grandes.
    Contudo não consigo recuperar esse tipo de informação do banco corretamente, voce teria um exemplo facil e rapido de como trabalhar com esse tipos de campos do Mysql ?

    Obrigado.

    Responder
  22. rogerio
    rogerio says:

    Ola Amigo,

    Sou do tempo do db3 , depois delphi 1,2,3,4,5 —
    agora estou querendo me abilitar para o delphi XE, minha duvida esta no banco de dados. Antes usava paradox criava a tabela , depois utilizava os comp. do delphi para acessar. Estou confuso com a aba Data explorer, Como criar as tabelas , qual banco de dados usar . tenho que instalar algo mais ?

    Responder
  23. Marlon
    Marlon says:

    Olá pessoal,

    estou utilizando as transoçoes do DBExpress, porem ao efetuar o COMMIT( aDBXConn.CommitFreeAndNil(aDBXTrans); ),

    o mesmo seta AUTOCOMMIT=1, porem eu nao quero que isso aconteca, quero que o mesmo fique 0 (OFF), alguem já passou por isso?

    abaixo o trecho do debug onde minha aplicação faz isso:

    MySQL – mysql_real_query
    MySQL – mysql_field_count
    MySQL – mysql_affected_rows
    COMMIT
    MySQL – mysql_real_query
    SET AUTOCOMMIT=1

    Responder
  24. Marlon
    Marlon says:

    Observação: No MYSQL existe o parametro AUTOCOMMIT, caso o mesmo esteja setado = 0 (ON), o Rollback não é respeitado, por isso a necessidade de deichar ele sempre OFF.

    Att,

    Responder
  25. Godinho
    Godinho says:

    Andreano como faço para usar um arquivo.ini localizado em outro lugar doq ue é comum
    Exe . DBXConnection := TDBXConnectionFactory.GetConnectionFactory.GetConnection(‘teste50′,’sysdba’,’masterkey’) ;. Eu queria substituir o arquivo padrao dbxconnections.ini
    que esta presente no delhi 10 , por um outro com outro nome e local..

    Responder
  26. duda
    duda says:

    Hola Andreano, podrias dejar un ejemplo de como iniciar una transaccion caundo se utiliza datasnap en varias capas fisicamente separadas, pues desde el lado del cliente si hacemos el codigo que indicas mas arriba, no se inicia ninguna transaccion explicita pues el cliente se conecta a travez de DATASNAP al servidor, mientras que tu ejemplo supone que la conexion se hace desde un cliente que tiene acceso directo al driver de interbase. desde ya muchas gracias.

    Responder
  27. Dowglas Maia
    Dowglas Maia says:

    Boa Tarde, há faz que postaram neste tópico, mas vi agora, estou estudando Delphi ja Algum tempo, e aibda não cosegui fazer uma conexão COM DBexpres, sempre aparece uma massagem Dizendo q não tenho o Driver DBx alguém Pode minha ajudar com esses poblema.?

    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 *


Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.