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.
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.
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”.
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)
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?
É isso mesmo vários objetos. Vou preparar um post sobre isso. boa idéia.
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
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!
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.
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.
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..
Oi Rafael, por padrão ela já vem habilitada, de onde você baixou essa versão?
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.
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.
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.
Oi Leandro,
Leia esse artigo http://www.andreanolanusse.com/pt/copiando-estrutura-e-dados-de-um-dbxreader-para-clientdataset-datasnap-2010/
Não entendo porque copiar para um TDataSet sendo que já existe o método para copiar para um TClientDataSet, por favor explique porque você precisaria disso.
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.
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..
Jovany,
Nunca vi esse erro, mas reinstalar é sempre uma alternativa.
Faz isso e posta aqui o resultado.
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
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) !
Rafael e Carlos este artigo esclarece as dúvidas de vocês http://www.andreanolanusse.com/pt/como-utilizar-parametros-em-dbexpress-dbx-framework/
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
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.
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…
Cleyton,
Por favor entre em contato com nosso suporte técnico, eles irão lhe ajudar com este problema, com certeza está ligado a instalação da versão 2010 e alguma versão anterior. Você pode obter suporte em http://support.embarcadero.com
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,
@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
@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.
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.
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 ?
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
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,
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..
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.
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.?