Clipper On Line • Ver Tópico - Firebird no Xharbour
Página 1 de 3

Firebird no Xharbour

MensagemEnviado: 09 Out 2009 15:53
por alexscava
Preciso de uma ajuda de como conectar o firebird no xharbour de forma nativa, sei que ele tem suporte, mas não consegui descobir como fazer a conexão.

Re: Firebird no Xharbour

MensagemEnviado: 09 Out 2009 19:33
por alxsts
Olá!

Seja bem-vindo Alex!

Sugiro que você utilize o recurso de busca do próprio fórum. Vai encontrar vários tópicos relacionados. Um deles é:
http://www.pctoledo.com.br/forum/viewtopic.php?f=42&t=9463&p=53735&hilit=Firebird+no+Xharbour#p53735

Re: Firebird no Xharbour

MensagemEnviado: 02 Nov 2009 22:06
por sygecom
Olá alexscava,
De forma Nativa que eu conheça apenas com SQLRDD, porem eu tenho uma versão de Setembro de 2009 e está me dando problemas ao tentar alterar uma estrutura de uma tabela, e meu prazo de suporte acabou, não sei mais a quem recorrer e nem como resolver, então se for adquirir lhe recomendo que teste, mas teste muitíssimo antes de realmente adquirir, por que depois, só Deus sabe como fica.

Re: Firebird no Xharbour

MensagemEnviado: 03 Nov 2009 12:11
por gvc
VC já viu que na pasta de contrib do xHarbour tem uma pasta firebird.
Além disso, vc pode usar ADO para acessar suas tabelas FireBord.

Re: Firebird no Xharbour

MensagemEnviado: 03 Nov 2009 23:36
por sygecom
Olá Gvc,
Parece que essa LIB está incompleta, agora via ADO o Rochinha já postou uns bons exemplos que pode ajudar a usar ADO com qualquer SGBD, que acredito ser uma boa opção mesmo.

Re: Firebird no Xharbour [Com exemplo]

MensagemEnviado: 04 Nov 2009 22:31
por RamonXHB
Eu uso Firebird com ADODB/OLEDB, não é com a lib do Rochinha, é direto mesmo, só com comandos sql, funciona perfeitamente, não incomoda e não estou dependente de nada, já que funciona tanto com xharbour como com harbour, que já uso a bastante tempo...
E posso afirmar que é uma excelente opção.
Um exemplo poderá ser baixado em : http://www.pctoledo.com.br/download/agenda.rar
Dentro do fonte agenda2.prg estão instruções para a instalação e utilização do programa.
Esta é uma versão com Firebird Embeded, ou seja, não precisa estar com o firebird instalado.
Basta instalar o driver odbc e executar o programa.

Re: Firebird no Xharbour

MensagemEnviado: 05 Nov 2009 10:55
por gvc
Ah. Mas agora o colega RamonXHB vai ter que postar um bom exemplo para nos ver-mos como funciona.
Ok. Ok. Brincadeiras a parte, gostaria de ver como funciona esse seu acesso ao FB. Alem de ficar um ótimo exemplo para os demais colegas aqui do Forum.
"Conhecimento não ocupa espaço." (Sr. Spock)
"Especifique." (Esposa do Sr. Spock)

Re: Firebird no Xharbour

MensagemEnviado: 06 Nov 2009 09:41
por RamonXHB
Vejam a minha mensagem anterior, lá está o link pro exemplo...

Re: Firebird no Xharbour

MensagemEnviado: 06 Nov 2009 16:13
por Toledo
Ramon, só uma dúvida... como seria executar este programa na rede, eu teria que instalar tanto o Firebird Embeded e o drive ODBC em todos os micros da rede?

Abraços,

Re: Firebird no Xharbour

MensagemEnviado: 06 Nov 2009 19:53
por RamonXHB
A idéia do firebird embarcado é não haver instalação do firebird na máquina.
O Firebird embeded ou embarcado, é totalmente monousuário, pois o arquivo do banco de dados fica travado para acesso para qualquer outra aplicação.
É util em situações como a agenda, que só o usuário da máquina vai utilizar.
No caso de ter um firebird já instalado na máquina, por exemplo, a versão 2.1, o firebird do exemplo é a 1.5, não vai afetar em nada, pois a versão embarcada rodará à parte...
Quanto a instalação do driver odbc, terá de ser feita em cada maquina, mas pode ser feita pelo próprio programa, não é necessário fazer à parte.
Há também a possibilidade de uso de provider oledb, mas também será necessária a instalação, que pode ser feita da mesma maneira que o driver odbc.
Fazendo do modo descrito acima, para o usuário, é básicamente copiar o exemplo em um diretório qualquer e criar um atalho e executar a aplicação.
Se for o caso de utilização em rede/multiusuario, instala-se o firebird e o arquivo FDB no servidor(versão normal, superserver ou classic) sem a aplicação.
Nas estações, o executavel com a dll do banco e a dll do drive odbc/oledb, mais nada.

Re: Firebird no Xharbour

MensagemEnviado: 07 Nov 2009 09:15
por DLZ
Ola..
Utilizo Firebird com Delphi já e é um banco legal de trabalhar.
Só uma dúvida:
essa lib ADODB/OLEDB é free ?

Re: Firebird no Xharbour

MensagemEnviado: 07 Nov 2009 10:05
por RamonXHB
É free sim, e o xharbour e o harbour tem suporte pra isso a muito tempo...
O suporte a Oledb/Adodb é o Mdac 2.8 que já vem default no windows a partir do XP e que pode ser instalado nas versões anteriores, facilmente, o modo de programar é o mesmo tanto no Delphi, Xharbour, Harbour, VB, etc...
Tem a principal vantagem a facilidade de mudança de banco de dados, só trocando a string de conexão.
Além de poder fazer conexão local ou remota, só através de configurações na string de conexão.
É ótimo naquelas situações que o cliente te diz "Olha, gostei muito do sistema, ele atenderia nossas necessidades, mas o banco de dados usado não é homologado pra uso aqui na empresa, vc desenvolveu em firebird, mas nós usamos Sql Server...", aí vc responde: "Sem problemas, nós migramos a base para seu banco de dados...", e não perde a venda.
Outra vantagem, diferente do uso de RDD´s que criam uma série de campos para controle do RDD nas tabelas, é o fato de você poder acessar bases de dados de outros sistemas e capturar dados para o seu sistema, já que não precisa de alterações já que não se está usando RDD´s para acesso.
Não estou dizendo que ferramentas que simulam o uso de DBF´s não tem sua utilidade, muito pelo contrario, mas no caso de desenvolvimento de sistemas novos, entendo que devemos abraçar definitivamente o uso do SQL em nossos sistemas.

Re: Firebird no Xharbour

MensagemEnviado: 09 Nov 2009 07:16
por TerraSoftware
Parece tudo muito interessante, mas ninguem tocou no assunto da velocidade de acesso ao banco, como fica esta questao? Visto que nem sempre nossos clientes dispoem de maquinas de alta performace. Aqui na empresa onde trabalho tem o pessoal do delphi que sempre diz que acesso ao banco de dados tem que ser nativo, fora isso é lentidao na certa. O bom e velho dbf pode ter (e tem) vários problemas, mas sua velocidade é inquestionavel, principalmente quando usamos emulacao de terminal.

Caros colegas, nao estou acusando a ferramenta exposta aqui (até por que nao tenho conhecimento para isso), estou questionando, pois tambem me interesso muito por base de dados relacional no xharbour, gostaria que os colegas que ja fazem uso postasem suas experiencias no quesito "velocidade".

Re: Firebird no Xharbour

MensagemEnviado: 09 Nov 2009 08:00
por DLZ
é free ?? q blz ??
Sr. Ramon, onde consigo essa Lib ? Documentação, exemplos etc ??
Estou muito afim de dar uma olhada nisso..

Re: Firebird no Xharbour

MensagemEnviado: 09 Nov 2009 09:24
por RamonXHB
Não é lib, oledb/adodb faz parte do windows xp, e pode ser instalado nas outras versões, se necessário baixar de http://www.meusdownloads.com.br/p.jsp?ppID=f946
A documentação vc encontra dentro do agenda.rar.
A velocidade é bem satisfatória, tanto em rede local como remota, é obvio e evidente que não se programa da mesma maneira que com os dbfs, não se concebe fazer uma query num SGBD que retorne milhares de registros, pois não há nada que justifique tal coisa...
O que os programadores se ressentem normalmente é ter que mudar de fazer browses em tabelas com um milhão de registros, quando na realidade vai precisar de 100, 200, ou 300...
O foco da programação deve ser sempre como se o cliente fosse usar o sistema de forma remota, e basear o desenvolvimento nesta visão.
Mas cada um faz do modo que acha melhor, testem , estudem o exemplo, e vejam se vale a pena ou não.
No exemplo da agenda, tem tudo o que precisa, incluir, excluir, alterar, selecionar uma determinada fixa de registros.
O resto é variação em cima deste tema.

Re: Firebird no Xharbour

MensagemEnviado: 26 Nov 2009 01:20
por gvc
O download já se perdeu.
Vc poderia ver com o Toledo ou o Maligno para colocar neste sitio ou no Maligno para download?

Re: Firebird no Xharbour

MensagemEnviado: 26 Nov 2009 07:28
por Toledo
O arquivo exemplo já está no meu servidor... segue abaixo o link:

http://www.pctoledo.com.br/download/agenda.rar

Ramon, se você quiser, é só editar a sua mensagem e colocar o link acima.

Abraços,

Re: Firebird no Xharbour

MensagemEnviado: 26 Nov 2009 08:31
por RamonXHB
Já editei o tópico que tem o endereço de download...

Firebird no Xharbour

MensagemEnviado: 14 Mar 2013 09:27
por viniciuspc
desenterrando o topico ! (A)

Precisamos utilizar um banco Firebird 1.5 que temos aqui, para exportação das tabelas DBF. Estamos usando o Harbour 3.0 com o MSVC (melhor performace) e acabei seguindo o exemplo do diretorio ..\contrib\hbfbird\tests\test.prg

Como já tinhamos o Firebird instalado, foi necessario apenas colocar o arquivo fbclient.dll na mesma pasta do executavel (se não tiver, ele nem entra...) e adaptamos o exemplo a nossa necessidade! funcionou perfeitamente.

Como temos uma possibilidade de alguns usuarios (temos em media mais de 5 mil usuarios no Brasil) não terem o Firebird instalado, então alteramos a conecção para o Firebird Embedded (Embarcado), bastou baixar o Firebird Embedded, copiar o arquivo fbembed.dll para fbclient.dll na pasta do executavel, e alteramos a variavel cServer do exemplo (test.prg)

Original LOCAL cServer := "localhost:"
Para LOCAL cServer := ""

A principio ficou OK, sem necessidade de instalação de ODBC e SGCD a parte.

Agora vem a parte dos testes... validar a aplicação nas demais plataformass Windows, mesmo com o Firebird instalado (2.0 ou 2.5) ou não.

Bom, fica ai a dica!

:xau

Firebird no Xharbour

MensagemEnviado: 15 Mar 2013 16:42
por RamonXHB
que tal você usar um exemplo ???

Firebird no Xharbour

MensagemEnviado: 18 Mar 2013 09:49
por janio
A velocidade é bem satisfatória, tanto em rede local como remota, é obvio e evidente que não se programa da mesma maneira que com os dbfs, não se concebe fazer uma query num SGBD que retorne milhares de registros, pois não há nada que justifique tal coisa...


Ja vi alguns colegas tocarem nessa questao "mostrar so os dados que interessam". Ocorre que ha situações que não vejo como aplicar a lógica disso! Se eu tenho um cadastro de produtos com 200.000 itens, por exemplo, e eu mostro um browse para o usuário procurar o produto q deseja... como de 200.000 produto eu irei mostrar apenas 10.000 se eu não sei qual produto o usuario deseja encontrar? O usuário pode querer encontrar qualquer um dos 200.000 cadastrados!

Pra pesquisa letra-a-letra como tenho no meu sistema, num vejo como aplicar essa lógica

Firebird no Xharbour

MensagemEnviado: 18 Mar 2013 15:01
por Poka
Olá a todos

Vinicius
Estou começando a mexer com Firebird agora. Usando o teste da contrib do harbour, consigo criar o arquivo , mas na linha da conexão dá o seguinte erro.

oServer := TFBServer():New( cServer + cDatabase, cUser, cPass, nDialect )


Error: Unresolved external '_HB_FUN_HB_DEFAULT' referenced from C:\MINIGUI\HARBOUR\LIB\HBFBIRD.LIB|tfirebrd

o que está faltando?

Janio, concordo plenamente contigo.
pra resolver o problema de tbrowse lento, fiz uma rotina que só mostro na tela num arquivo temporario, os registros que cabem na tela, aí sim resolve, praticamente não importa o tamanho do arquivo. Na empresa tava muito lento, agora até via romoto com TeamWiewer fica rápido, mesmo com pesquisa letra a letra.

Poka

Firebird no Xharbour

MensagemEnviado: 26 Mar 2013 14:49
por sygecom
Poka,
Você deve está usando Harbour, essa função está em RTL.LIB, quando se usa o hbmk2 para compilar ele já deve ir automaticamente.

Firebird no Xharbour

MensagemEnviado: 27 Mar 2013 08:31
por Poka
Leonardo, obrigado por responder.

Utilizo Harbour Minigui Extend Edition 2.1.1 – 2012-05-16
Harbour 3.2.0dev (rev. 17477)
Utilizo o xDevStudio para compilar.
O arquivo HBRTL já está relacionado na compilação.
Se tiver mais alguma informação, fico muito agradecido.

Poka

Firebird no Xharbour

MensagemEnviado: 29 Set 2016 21:11
por Hasse
Boa noite Poka.

Uso a MiniGui 3.4.1, Harbour 3.2.0, IDE do Roberto Lopez V 1.0.8, compila com hbmk2.

Harbour 3.2.0dev (r1506261250)
Copyright (c) 1999-2015, http://harbour-project.org/
C:/Users/Padrao/AppData/Local/Temp/hbmk_wewqcg.dir/small_06.o:small_06.c:(.data+0x78): undefined reference to `HB_FUN_TFBSERVER'
collect2.exe: error: ld returned 1 exit status
hbmk2[Small_06]: Erro: Executando linkeditor. 1
gcc.exe C:/Users/Padrao/AppData/Local/Temp/hbmk_wewqcg.dir/small_06.o C:/Users/Padrao/AppData/Local/Temp/hbmk_wewqcg.dir/hbmk_v6uxe3.o G:/DEV2/DentalOff/_temp.o -mwindows -Wl,--start-group -lhmg -lcrypt -ledit -leditex -lgraph -lini -lreport -lhfcl -lmsvfw32 -lvfw32 -lhbct -lhbwin -lhbmzip -lminizip -lhbmemio -lhbmisc -lhbmysql -lmysql -lhbtip -lhbsqlit3 -lsddodbc -lrddsql -lsddmy -lhbodbc -lodbc32 -lhbhpdf -lhbfimage -lhbpgsql -lhbnetio -lxhb -lpng -llibhpdf -lhbvpdf -lhbzebra -lhbextern -lhbdebug -lhbvmmt -lhbrtl -lhblang -lhbcpage -lgtcgi -lgtpca -lgtstd -lgtwin -lgtwvt -lgtgui -lhbrdd -lhbuddall -lhbusrrdd -lrddntx -lrddcdx -lrddnsx -lrddfpt -lhbrdd -lhbhsx -lhbsix -lhbmacro -lhbcplr -lhbpp -lhbcommon -lhbmainwin -lkernel32 -luser32 -lgdi32 -ladvapi32 -lws2_32 -liphlpapi -lwinspool -lcomctl32 -lcomdlg32 -lshell32 -luuid -lole32 -loleaut32 -lmpr -lwinmm -lmapi32 -limm32 -lmsimg32 -lwininet -lhbpcre -lhbzlib -Wl,--end-group -oSmall_06.exe -LC:/hmg.3.4.1/harbour/lib/win/mingw -LC:/hmg.3.4.1/lib

hbmk2: Dica: Adicionar op‡Æo 'hbfbird.hbc' faltando nas fun‡äes: TFBServer()


Onde encontro a Função TFBServer e outras funções desta mesma classe.

Firebird no Xharbour

MensagemEnviado: 06 Out 2016 10:31
por Poka
Olá a todos

Hasse, desculpe estar só respondendo agora, estou enrolado com CT-e aqui, que nem deu tempo.
Essa função TFBServer, deve estar dentro hbfbird.lib.

Eu não isso essa função, eu a compilo somente para usar a criação de banco de dados fdb.
Se essa lib estivesse funcionando corretamente, talvez não precisaria do ODBC, aí sim ficaria nativo, alguém pode explicar melhor se estiver enganado.

Eu uso;

Harbour Minigui Extend 2.5.4 – 2015.10.21
Harbour 3.2.0dev (r1510132105)

Para compilar eu uso xDevStudio ( parabéns para quem desenvolveu essa ferramenta) nunca usei hbmk2.
Não entendo bem, acho que se alguém pode até explicar melhor do que eu. Tentei usar as funções da hbfbird.lib, mas dava muito erro, então uso Firebird + Odbc. Compilo essa lib somente para criar os arquivos mesmos. Para quem que mudar de banco de dados, acho que o caminho + fácil mesmo é esse, Firebird + Odbc. O firebird e o ODBC instala no “servidor” e nos terminais somente o ODBC, a instalação pode ser feita até pelo seu sistema mesmo, sem ter que entra na Internet, é rápido.

Não sou expert como os colegas daqui do fórum, apesar de estar programando há 25 anos, muita coisa que vocês dizem aqui foge do meu conhecimento, deixo de aprender muita coisa também, por causa do meu inglês que é zero. Mas vou fazendo o feijão com arroz mesmo.
Já coloquei um sistema pequeno com firebird, e está funcionando muito bem, estou passando o sistema maior agora, mas vai demorar uns meses ainda.

Quando tenho duvidas com comandos SQL pergunto aqui no fórum também, e assim vamos indo.
Sobre a velocidade do Firebird
Gostei bastante, fiz um teste com uma tabela de 1.000.000 de registros. No meu computador que é bem fraquinho, demorou 15 segundos (muito tempo), levei na empresa, 3 segundos, achei ótimo, isso procurando “SILVA” por exemplo no arquivo inteiro, aí mostro só os selecionados no
Uma coisa que gostei muito, é que qualquer terminal, por + ruim quem seja, a velocidade é igual a do servidor.

Sobre o Browser

Com um milhão de registros fica inaceitável, trazer todos os registros, nos dbs tinha feito uma paginação de dados onde só mostrava os registros que cabiam na tela, ficou super rápido , mas agora com firebird vou ter que fazer algo semelhante, O firebird pensando nisso já tem funções internas que facilita ainda mais essa rotina que são , First, Skip e Rows, não mexi nessa parte ainda,vou por o sistema para funcionar primeiro, depois altero essas rotinas, senão vou ficar o resto da vida terminando.

Porque escolhi o Firebird.

Quando fui sair do dbf para SQL, escolhi três opções.
MYSQL, POSTGRESQL, FIREBIRD
Não posso me dar ao luxo de aprender os três e ver o melhor, perde-se muito tempo, já tenho 62 anos e não posso dispender desse tempo. Então li muito na internet, sobre os esses bancos , opiniões, testes de velocidade, etc.
O MYSQL até onde entendi, embora muitos dizem o contrário, não é free, é free se vc for distribuir o seu sistema gratuitamente.
Entre os outros dois, acabei escolhendo o Firebird, e não me arrependi por isso, uma das coisas que influenciou no Firebird, não sei se esse seria o termo correto, a sua portabilidade.

Arquivo anexo:
Contém os arquivos exe do exemplo, e de intalação de Firebird e ODBC ( para WIn 32)
Descompacte em uma pasta qualquer esse exemplo.

Um abraço

Poka

Firebird no Xharbour

MensagemEnviado: 06 Out 2016 11:46
por Hasse
Valeu meu caro.

Vou digerir todas as informações que você colocou.

Eu também escolhi o Firebird, mas não pelos mesmos motivos, mas por ter tido contatos anteriores com ele, e gostei.

Obrigado.

Firebird no Xharbour

MensagemEnviado: 06 Out 2016 15:27
por jairfab
TFBServer realmente está escrito em harbour e não compatível com xharbour, mas tudo que tem nesta classe é feito utilizando funções em C que é compatível com harbour e xharbour, eu fiz um trabalho que precisava importar e exportar dados dbf para banco firebird nativo e tive este mesmo problema.

Foi então que fiz uma verificação na class TFBServer e vir que tudo que a classe faz é exatamente utilizar as funçôes que estar na lib ou seja apenas tratar os retorno da funções escritas em C.


*** Utilizando a class TFBServer
oServer := TFBServer():New( cServer + cDatabase, cUser, cPass, nDialect )

*** Utilizando a função  FBConnect o resultado seria o mesmo 
oServer := FBConnect( cServer + cDatabase, cUser, cPass )



Observe o que tem na lib alem da class TFBServer

#include <time.h>

/* NOTE: Ugly hack to avoid this error when compiler with BCC 5.8.2 and above:
         Error E2238 C:\...\Firebird-2.1.1\include\ibase.h 82: Multiple declaration for 'intptr_t' */
#if ( defined( __BORLANDC__ ) && __BORLANDC__ >= 0x582 )
   /* Prevent inclusion of <stdint.h> from hbdefs.h */
   #define __STDINT_H
#endif

#include "hbapi.h"
#include "hbapierr.h"
#include "hbapiitm.h"

#include "ibase.h"

#ifndef ISC_INT64_FORMAT
   #define ISC_INT64_FORMAT PFLL
#endif

/* GC object handlers */

static HB_GARBAGE_FUNC( FB_db_handle_release )
{
   isc_db_handle * ph = ( isc_db_handle * ) Cargo;

   /* Check if pointer is not NULL to avoid multiple freeing */
   if( ph && * ph )
   {
      ISC_STATUS_ARRAY status;

      /* Destroy the object */
      isc_detach_database( status, ph );

      /* set pointer to NULL to avoid multiple freeing */
      * ph = 0;
   }
}

static void hb_FB_db_handle_ret( isc_db_handle p )
{
   if( p )
   {
      isc_db_handle * ph = ( isc_db_handle * )
            hb_gcAlloc( sizeof( isc_db_handle ), FB_db_handle_release );

      * ph = p;

      hb_retptrGC( ph );
   }
   else
      hb_retptr( NULL );
}

static isc_db_handle hb_FB_db_handle_par( int iParam )
{
   isc_db_handle * ph = ( isc_db_handle * ) hb_parptrGC( FB_db_handle_release, iParam );

   return ph ? * ph : 0;
}

/* API wrappers */

HB_FUNC( FBCREATEDB )
{
   if( hb_pcount() == 6 )
   {
      isc_db_handle newdb = ( isc_db_handle ) 0;
      isc_tr_handle trans = ( isc_tr_handle ) 0;
      ISC_STATUS status[ 20 ];
      char create_db[ 1024 ];

      const char *   db_name = hb_parcx( 1 );
      const char *   user    = hb_parcx( 2 );
      const char *   pass    = hb_parcx( 3 );
      int            page    = hb_parni( 4 );
      const char *   charset = hb_parcx( 5 );
      unsigned short dialect = ( unsigned short ) hb_parni( 6 );

      hb_snprintf( create_db, sizeof( create_db ),
                   "CREATE DATABASE '%s' USER '%s' PASSWORD '%s' PAGE_SIZE = %i DEFAULT CHARACTER SET %s",
                   db_name, user, pass, page, charset );

      if( isc_dsql_execute_immediate( status, &newdb, &trans, 0, create_db, dialect, NULL ) )
         hb_retnl( isc_sqlcode( status ) );
      else
         hb_retnl( 1 );
   }
   else
      hb_retnl( 0 );
}

HB_FUNC( FBCONNECT )
{
   ISC_STATUS_ARRAY status;
   isc_db_handle    db = ( isc_db_handle ) 0;
   const char *     db_connect = hb_parcx( 1 );
   const char *     user = hb_parcx( 2 );
   const char *     passwd = hb_parcx( 3 );
   char             dpb[ 128 ];
   short            i = 0;
   int              len;

   /* TOFIX: Possible buffer overflow. Use hb_snprintf(). */
   dpb[ i++ ] = isc_dpb_version1;
   dpb[ i++ ] = isc_dpb_user_name;
   len = ( int ) strlen( user );
   if( len > ( int ) ( sizeof( dpb ) - i - 4 ) )
      len = ( int ) ( sizeof( dpb ) - i - 4 );
   dpb[ i++ ] = ( char ) len;
   hb_strncpy( &( dpb[ i ] ), user, len );
   i += ( short ) len;
   dpb[ i++ ] = isc_dpb_password;
   len = ( int ) strlen( passwd );
   if( len > ( int ) ( sizeof( dpb ) - i - 2 ) )
      len = ( int ) ( sizeof( dpb ) - i - 2 );
   dpb[ i++ ] = ( char ) len;
   hb_strncpy( &( dpb[ i ] ), passwd, len );
   i += ( short ) len;

   if( isc_attach_database( status, 0, db_connect, &db, i, dpb ) )
      hb_retnl( isc_sqlcode( status ) );
   else
      hb_FB_db_handle_ret( db );
}

HB_FUNC( FBCLOSE )
{
   isc_db_handle db = hb_FB_db_handle_par( 1 );

   if( db )
   {
      ISC_STATUS_ARRAY status;

      if( isc_detach_database( status, &db ) )
         hb_retnl( isc_sqlcode( status ) );
      else
         hb_retnl( 1 );
   }
   else
      hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}

HB_FUNC( FBERROR )
{
   char msg[ 1024 ];

   isc_sql_interprete( ( short ) hb_parni( 1 ) /* sqlcode */,
                       msg, sizeof( msg ) );

   hb_retc( msg );
}

HB_FUNC( FBSTARTTRANSACTION )
{
   isc_db_handle db = hb_FB_db_handle_par( 1 );

   if( db )
   {
      isc_tr_handle trans = ( isc_tr_handle ) 0;
      ISC_STATUS_ARRAY status;

      if( isc_start_transaction( status, &trans, 1, &db, 0, NULL ) )
         hb_retnl( isc_sqlcode( status ) );
      else
         hb_retptr( ( void * ) ( HB_PTRDIFF ) trans );
   }
   else
      hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}

HB_FUNC( FBCOMMIT )
{
   isc_tr_handle trans = ( isc_tr_handle ) ( HB_PTRDIFF ) hb_parptr( 1 );

   if( trans )
   {
      ISC_STATUS_ARRAY status;

      if( isc_commit_transaction( status, &trans ) )
         hb_retnl( isc_sqlcode( status ) );
      else
         hb_retnl( 1 );
   }
   else
      hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}

HB_FUNC( FBROLLBACK )
{
   isc_tr_handle trans = ( isc_tr_handle ) ( HB_PTRDIFF ) hb_parptr( 1 );

   if( trans )
   {
      ISC_STATUS_ARRAY status;

      if( isc_rollback_transaction( status, &trans ) )
         hb_retnl( isc_sqlcode( status ) );
      else
         hb_retnl( 1 );
   }
   else
      hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}

HB_FUNC( FBEXECUTE )
{
   isc_db_handle db = hb_FB_db_handle_par( 1 );

   if( db )
   {
      isc_tr_handle   trans = ( isc_tr_handle ) 0;
      const char *    exec_str = hb_parcx( 2 );
      ISC_STATUS      status[ 20 ];
      ISC_STATUS      status_rollback[ 20 ];
      unsigned short  dialect = ( unsigned short ) hb_parni( 3 );

      if( ISPOINTER( 4 ) )
         trans = ( isc_tr_handle ) ( HB_PTRDIFF ) hb_parptr( 4 );
      else
      {
         if( isc_start_transaction( status, &trans, 1, &db, 0, NULL ) )
         {
            hb_retnl( isc_sqlcode( status ) );
            return;
         }
      }

      if( isc_dsql_execute_immediate( status, &db, &trans, 0, exec_str, dialect, NULL ) )
      {
         if( ! ISPOINTER( 4 ) )
            isc_rollback_transaction( status_rollback, &trans );

         hb_retnl( isc_sqlcode( status ) );
         return;
      }

      if( ! ISPOINTER( 4 ) )
      {
         if( isc_commit_transaction( status, &trans ) )
         {
            hb_retnl( isc_sqlcode( status ) );
            return;
         }
      }

      hb_retnl( 1 );
   }
   else
      hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}

HB_FUNC( FBQUERY )
{
   isc_db_handle db = hb_FB_db_handle_par( 1 );

   if( db )
   {
      isc_tr_handle    trans = ( isc_tr_handle ) 0;
      ISC_STATUS_ARRAY status;
      XSQLDA *         sqlda;
      isc_stmt_handle  stmt = ( isc_stmt_handle ) 0;
      XSQLVAR *        var;

      unsigned short   dialect = ( unsigned short ) hb_parnidef( 3, SQL_DIALECT_V5 );
      int              i;
      int              num_cols;

      PHB_ITEM qry_handle;
      PHB_ITEM aNew;
      PHB_ITEM aTemp;

      if( ISPOINTER( 4 ) )
         trans = ( isc_tr_handle ) ( HB_PTRDIFF ) hb_parptr( 4 );
      else if( isc_start_transaction( status, &trans, 1, &db, 0, NULL ) )
      {
         hb_retnl( isc_sqlcode( status ) );
         return;
      }

      /* Allocate a statement */
      if( isc_dsql_allocate_statement( status, &db, &stmt ) )
      {
         hb_retnl( isc_sqlcode( status ) );
         return;
      }

      /* Allocate an output SQLDA. Just to check number of columns */
      sqlda = ( XSQLDA * ) hb_xgrab( XSQLDA_LENGTH( 1 ) );
      sqlda->sqln = 1;
      sqlda->version = 1;

      /* Prepare the statement. */
      if( isc_dsql_prepare( status, &trans, &stmt, 0, hb_parcx( 2 ), dialect, sqlda ) )
      {
         hb_xfree( sqlda );
         hb_retnl( isc_sqlcode( status ) );
         return;
      }

      /* Describe sql contents */
      if( isc_dsql_describe( status, &stmt, dialect, sqlda ) )
      {
         hb_xfree( sqlda );
         hb_retnl( isc_sqlcode( status ) );
         return;
      }

      /* Relocate necessary number of columns */
      if( sqlda->sqld > sqlda->sqln )
      {
         ISC_SHORT n = sqlda->sqld;
         sqlda = ( XSQLDA * ) hb_xrealloc( sqlda, XSQLDA_LENGTH( n ) );
         sqlda->sqln = n;
         sqlda->version = 1;

         if( isc_dsql_describe( status, &stmt, dialect, sqlda ) )
         {
            hb_xfree( sqlda );
            hb_retnl( isc_sqlcode( status ) );
            return;
         }
      }

      num_cols = sqlda->sqld;
      aNew = hb_itemArrayNew( num_cols );
      aTemp = hb_itemNew( NULL );

      for( i = 0, var = sqlda->sqlvar; i < sqlda->sqld; i++, var++ )
      {
         int dtype = ( var->sqltype & ~1 );

         switch( dtype )
         {
         case SQL_VARYING:
            var->sqltype = SQL_TEXT;
            var->sqldata = ( char * ) hb_xgrab( sizeof( char ) * var->sqllen + 2 );
            break;
         case SQL_TEXT:
            var->sqldata = ( char * ) hb_xgrab( sizeof( char ) * var->sqllen + 2 );
            break;
         case SQL_LONG:
            var->sqltype = SQL_LONG;
            var->sqldata = ( char * ) hb_xgrab( sizeof( long ) );
            break;
         default:
            var->sqldata = ( char * ) hb_xgrab( sizeof( char ) * var->sqllen );
            break;
         }

         if( var->sqltype & 1 )
            var->sqlind = ( short * ) hb_xgrab( sizeof( short ) );

         hb_arrayNew( aTemp, 7 );

         hb_arraySetC(  aTemp, 1, sqlda->sqlvar[ i ].sqlname );
         hb_arraySetNL( aTemp, 2, ( long ) dtype );
         hb_arraySetNL( aTemp, 3, sqlda->sqlvar[ i ].sqllen );
         hb_arraySetNL( aTemp, 4, sqlda->sqlvar[ i ].sqlscale );
         hb_arraySetC(  aTemp, 5, sqlda->sqlvar[ i ].relname );
         hb_arraySetNL( aTemp, 6, sqlda->sqlvar[ i ].aliasname_length ); /* support for aliases */
         hb_arraySetC(  aTemp, 7, sqlda->sqlvar[ i ].aliasname ); /* support for aliases */

         hb_arraySetForward( aNew, i + 1, aTemp );
      }

      hb_itemRelease( aTemp );

      if( ! sqlda->sqld )
      {
         /* Execute and commit non-select querys */
         if( isc_dsql_execute( status, &trans, &stmt, dialect, NULL ) )
         {
            hb_itemRelease( aNew );
            hb_retnl( isc_sqlcode( status ) );
            return;
         }
      }
      else
      {
         if( isc_dsql_execute( status, &trans, &stmt, dialect, sqlda ) )
         {
            hb_itemRelease( aNew );
            hb_retnl( isc_sqlcode( status ) );
            return;
         }
      }

      qry_handle = hb_itemArrayNew( 6 );

      hb_arraySetPtr( qry_handle, 1, ( void * ) ( HB_PTRDIFF ) stmt );
      hb_arraySetPtr( qry_handle, 2, ( void * ) ( HB_PTRDIFF ) sqlda );

      if( ! ISPOINTER( 4 ) )
         hb_arraySetPtr( qry_handle, 3, ( void * ) ( HB_PTRDIFF ) trans );

      hb_arraySetNL( qry_handle, 4, ( long ) num_cols );
      hb_arraySetNI( qry_handle, 5, ( int ) dialect );
      hb_arraySetForward( qry_handle, 6, aNew );

      hb_itemReturnRelease( qry_handle );
      hb_itemRelease( aNew );
   }
   else
      hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );

}

HB_FUNC( FBFETCH )
{
   PHB_ITEM aParam = hb_param( 1, HB_IT_ARRAY );

   if( aParam )
   {
      isc_stmt_handle  stmt = ( isc_stmt_handle ) ( HB_PTRDIFF ) hb_itemGetPtr( hb_itemArrayGet( aParam, 1 ) );
      XSQLDA *         sqlda = ( XSQLDA * ) hb_itemGetPtr( hb_itemArrayGet( aParam, 2 ) );
      ISC_STATUS_ARRAY status;
      unsigned short   dialect = ( unsigned short ) hb_itemGetNI( hb_itemArrayGet( aParam, 5 ) );

      /* TOFIX */
      hb_retnl( isc_dsql_fetch( status,
                                &stmt,
                                dialect,
                                sqlda ) == 100L ? -1 : isc_sqlcode( status ) );
   }
   else
      hb_retnl( 0 );
}

HB_FUNC( FBFREE )
{
   PHB_ITEM aParam = hb_param( 1, HB_IT_ARRAY );

   if( aParam )
   {
      isc_stmt_handle  stmt = ( isc_stmt_handle ) ( HB_PTRDIFF ) hb_itemGetPtr( hb_itemArrayGet( aParam, 1 ) );
      XSQLDA *         sqlda = ( XSQLDA * ) hb_itemGetPtr( hb_itemArrayGet( aParam, 2 ) );
      isc_tr_handle    trans = ( isc_tr_handle ) ( HB_PTRDIFF ) hb_itemGetPtr( hb_itemArrayGet( aParam, 3 ) );
      ISC_STATUS_ARRAY status;

      if( isc_dsql_free_statement( status, &stmt, DSQL_drop ) )
      {
         hb_retnl( isc_sqlcode( status ) );
         return;
      }

      if( trans )
      {
         if( isc_commit_transaction( status, &trans ) )
         {
            hb_retnl( isc_sqlcode( status ) );
            return;
         }
      }

      /* TOFIX: Freeing pointer received as parameter? We should at least set the item NULL. */
      if( sqlda )
         hb_xfree( sqlda );

      hb_retnl( 1 );
   }
   else
      hb_retnl( 0 );
}

HB_FUNC( FBGETDATA )
{
   PHB_ITEM aParam = hb_param( 1, HB_IT_ARRAY );

   if( aParam )
   {
      XSQLVAR *        var;
      XSQLDA *         sqlda = ( XSQLDA * ) hb_itemGetPtr( hb_itemArrayGet( aParam, 2 ) );
      ISC_STATUS_ARRAY status;
      ISC_QUAD *       blob_id;

      int pos = hb_parni( 2 ) - 1;

      if( ! sqlda || pos < 0 || pos >= sqlda->sqln )
      {
         hb_retnl( isc_sqlcode( status ) );
         return;
      }

      var = sqlda->sqlvar + pos;

      if( ( var->sqltype & 1 ) && ( *var->sqlind < 0 ) )
      {
         hb_ret(); /* null field */
      }
      else
      {
         struct tm times;
         char date_s[ 25 ];
         char data[ 1024 ];

         short dtype = var->sqltype & ~1;

         switch( dtype )
         {
         case SQL_TEXT:
         case SQL_VARYING:
            hb_retclen( var->sqldata, var->sqllen );
            break;

         case SQL_TIMESTAMP:
            isc_decode_timestamp( ( ISC_TIMESTAMP * ) var->sqldata, &times );
            hb_snprintf( date_s, sizeof( date_s ), "%04d-%02d-%02d %02d:%02d:%02d.%04d",
                         times.tm_year + 1900,
                         times.tm_mon + 1,
                         times.tm_mday,
                         times.tm_hour,
                         times.tm_min,
                         times.tm_sec,
                         ( int ) ( ( ( ISC_TIMESTAMP * ) var->sqldata )->timestamp_time % 10000 ) );
            hb_snprintf( data, sizeof( data ), "%*s ", 24, date_s );

            hb_retc( data );
            break;

         case SQL_TYPE_DATE:
            isc_decode_sql_date( ( ISC_DATE * ) var->sqldata, &times );
            hb_snprintf( date_s, sizeof( date_s ), "%04d-%02d-%02d", times.tm_year + 1900, times.tm_mon + 1, times.tm_mday );
            hb_snprintf( data, sizeof( data ), "%*s ", 8, date_s );

            hb_retc( data );
            break;

         case SQL_TYPE_TIME:
            isc_decode_sql_time( ( ISC_TIME * ) var->sqldata, &times );
            hb_snprintf( date_s, sizeof( date_s ), "%02d:%02d:%02d.%04d",
                         times.tm_hour,
                         times.tm_min,
                         times.tm_sec,
                         ( int ) ( ( *( ( ISC_TIME * ) var->sqldata ) ) % 10000 ) );
            hb_snprintf( data, sizeof( data ), "%*s ", 13, date_s );

            hb_retc( data );
            break;

         case SQL_BLOB:
            blob_id = ( ISC_QUAD * ) var->sqldata;
            hb_retptr( ( void * ) blob_id );
            break;

         case SQL_SHORT:
         case SQL_LONG:
         case SQL_INT64:
            {
               ISC_INT64 value;
               short field_width;
               short dscale;

               switch( dtype )
               {
               case SQL_SHORT:
                  value = ( ISC_INT64 ) *( short * ) var->sqldata;
                  field_width = 6;
                  break;

               case SQL_LONG:
                  value = ( ISC_INT64 ) *( long * ) var->sqldata;
                  field_width = 11;
                  break;

               case SQL_INT64:
                  value = ( ISC_INT64 ) *( ISC_INT64 * ) var->sqldata;
                  field_width = 21;
                  break;

               default:
                  value = 0;
                  field_width = 10;
                  break;
               }

               dscale = var->sqlscale;

               if( dscale < 0 )
               {
                  ISC_INT64 tens = 1;
                  short     i;

                  for( i = 0; i > dscale; i-- )
                     tens *= 10;

                  if( value >= 0 )
                     hb_snprintf( data, sizeof( data ), "%*" ISC_INT64_FORMAT "d.%0*" ISC_INT64_FORMAT "d",
                                  field_width - 1 + dscale,
                                  ( ISC_INT64 ) value / tens,
                                  -dscale,
                                  ( ISC_INT64 ) value % tens );
                  else if( ( value / tens ) != 0 )
                     hb_snprintf( data, sizeof( data ), "%*" ISC_INT64_FORMAT "d.%0*" ISC_INT64_FORMAT "d",
                                  field_width - 1 + dscale,
                                  ( ISC_INT64 ) ( value / tens ),
                                  -dscale,
                                  ( ISC_INT64 ) -( value % tens ) );
                  else
                     hb_snprintf( data, sizeof( data ), "%*s.%0*" ISC_INT64_FORMAT "d",
                                  field_width - 1 + dscale,
                                  "-0",
                                  -dscale,
                                  ( ISC_INT64 ) -( value % tens ) );
               }
               else if( dscale )
                  hb_snprintf( data, sizeof( data ), "%*" ISC_INT64_FORMAT "d%0*d", field_width, ( ISC_INT64 ) value, dscale, 0 );
               else
                  hb_snprintf( data, sizeof( data ), "%*" ISC_INT64_FORMAT "d", field_width, ( ISC_INT64 ) value );
            }

            hb_retc( data );
            break;

         case SQL_FLOAT:
            hb_snprintf( data, sizeof( data ), "%15g ", *( float * ) ( var->sqldata ) );
            hb_retc( data );
            break;

         case SQL_DOUBLE:
            hb_snprintf( data, sizeof( data ), "%24f ", *( double * ) ( var->sqldata ) );
            hb_retc( data );
            break;

         default:
            hb_ret();
            break;
         }
      }
   }
}

HB_FUNC( FBGETBLOB )
{
   isc_db_handle db = hb_FB_db_handle_par( 1 );

   if( db )
   {
      ISC_STATUS_ARRAY status;
      isc_tr_handle    trans = ( isc_tr_handle ) 0;
      isc_blob_handle  blob_handle = ( isc_blob_handle ) 0;
      short            blob_seg_len;
      char             blob_segment[ 512 ];
      ISC_QUAD *       blob_id = ( ISC_QUAD * ) hb_parptr( 2 );
      char             p[ 1024 ];
      ISC_STATUS       blob_stat;

      if( ISPOINTER( 3 ) )
         trans = ( isc_tr_handle ) ( HB_PTRDIFF ) hb_parptr( 3 );
      else
      {
         if( isc_start_transaction( status, &trans, 1, &db, 0, NULL ) )
         {
            hb_retnl( isc_sqlcode( status ) );
            return;
         }
      }

      if( isc_open_blob2( status, &db, &trans, &blob_handle, blob_id, 0, NULL ) )
      {
         hb_retnl( isc_sqlcode( status ) );
         return;
      }

      /* Get blob segments and their lengths and print each segment. */
      blob_stat = isc_get_segment( status, &blob_handle,
                                   ( unsigned short * ) &blob_seg_len,
                                   sizeof( blob_segment ), blob_segment );

      if( blob_stat == 0 || status[ 1 ] == isc_segment )
      {
         PHB_ITEM aNew = hb_itemArrayNew( 0 );

         while( blob_stat == 0 || status[ 1 ] == isc_segment )
         {
            PHB_ITEM temp;

            hb_snprintf( p, sizeof( p ), "%*.*s", blob_seg_len, blob_seg_len, blob_segment );

            temp = hb_itemPutC( NULL, p );
            hb_arrayAdd( aNew, temp );
            hb_itemRelease( temp );

            blob_stat = isc_get_segment( status, &blob_handle,
                                         ( unsigned short * ) &blob_seg_len,
                                         sizeof( blob_segment ), blob_segment );
         }

         hb_itemReturnRelease( aNew );
      }

      if( isc_close_blob( status, &blob_handle ) )
      {
         hb_retnl( isc_sqlcode( status ) );
         return;
      }

      if( ! ISPOINTER( 3 ) )
      {
         if( isc_commit_transaction( status, &trans ) )
         {
            hb_retnl( isc_sqlcode( status ) );
            return;
         }
      }
   }
   else
      hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}


Firebird no Xharbour

MensagemEnviado: 06 Out 2016 15:37
por jairfab
Segue um pequeno exemplo utilizando firebird nativo

#include "common.ch"
#include "Fileio.ch" 
#define CRLF CHR(13)+CHR(10)

FUNCTION MAIN

LOCAL ndialect  := 3
LOCAL cUser     := "SYSDBA"
LOCAL cPass     := "masterkey"

CLS
*      ? FBCreateDB( cServer + cDatabase, cUser, cPass, nPageSize, cCharSet, nDialect )
cls
RDDSetDefault("DBFCDX")
*cBanco='192.168.1.167:C:\DB\JAIR.FDB'
*cBanco='189.38.89.220:C:\JAIR.FDB'
cBanco:='C:\DB\JAIR.FDB'
db    := FBConnect(cBanco, "sysdba", "masterkey")

IF HB_ISNUMERIC( db )
  * MSGSTOP("Não foi possivel a conexão com o banco de dados :"+cBanco)
   RETURN .T.
ENDIF
IF ISNUMBER(db)
*  MSGSTOP("Não foi possivel a conexão com o banco de dados :"+cBanco)
   RETURN .T.
ENDIF

trans := FBStartTransaction( db )
IF HB_ISNUMERIC( trans )
*  MSGSTOP("Não foi possivel executar a transação")
   RETURN .T.
ENDIF
*                    1          2         3        4      5
cSql     := "SELECT CODCLI, CODEMPRESA, TIPOCLI, CONTA, CONTAFOR FROM V_CLI "
trans    := FBStartTransaction(db)
vPlanoCt := FBQuery(db, cSql, ndialect, trans)
*-----------------------------------------------------------------------*
* Carrega informações para a contabilização                             *
*-----------------------------------------------------------------------*

DO WHILE ( fetch_stat := FBFetch( vPlanoCt ) ) == 0
   V01 :=FBGetData( vPlanoCt, 1 )
   V02 :=FBGetData( vPlanoCt, 2 )
   V03 :=FBGetData( vPlanoCt, 3 )
   V04 :=FBGetData( vPlanoCt, 4 )
   V05 :=FBGetData( vPlanoCt, 5 )
   ? V01, V02, V03, V04, V05

ENDDO
*-----------------------------------------------------------------------*
* Fecha conexao com o banco de dados                                    *
*-----------------------------------------------------------------------*
FBFree(vPlanoCt)
FBClose(db)

return nil


Firebird no Xharbour

MensagemEnviado: 06 Out 2016 18:02
por JoséQuintas
Ja vi alguns colegas tocarem nessa questao "mostrar so os dados que interessam". Ocorre que ha situações que não vejo como aplicar a lógica disso! Se eu tenho um cadastro de produtos com 200.000 itens, por exemplo, e eu mostro um browse para o usuário procurar o produto q deseja... como de 200.000 produto eu irei mostrar apenas 10.000 se eu não sei qual produto o usuario deseja encontrar? O usuário pode querer encontrar qualquer um dos 200.000 cadastrados!
Pra pesquisa letra-a-letra como tenho no meu sistema, num vejo como aplicar essa lógica


Isso é relativo, justamente aí entra "não pensar igual DBF".

DBF:
200.000 produtos, registro de 2.000 bytes, numa tela cabendo 40 produtos, 80.000 bytes ( 80kb) pela rede.
Pelo menos 2 arquivos abertos e compartilhados (DBF + CDX), e terminal conversando com servidor.
Registros lidos um de cada vez, com várias consultas ao servidor durante a montagem do browse, e depois também.
Terminais talvez "brigando entre si", pra acessar os dados.
Mesmo numa rede de 100MB, são várias consultas.

Server:
O terminal pede pro servidor e vém pronto, consulta com código + descrição, 50 bytes, aonde o DBF gastava a rede pra 40 registros, agora cabem 1.600.
Ou que seja, 1MB pela rede para o arquivo inteiro.
Uma única consulta ao servidor, numa rede de 100MB, 1 segundo e servidor e rede estão liberados para os outros terminais.

As máquinas atuais vém com placa de rede de 1GB. Pra DBFs, o ganho é pequeno, porque continua sendo um registro por vez, já nessa consulta de 200.000 produtos em cliente/servidor...

Em termos de movimentação de dados/rede, a diferença entre DBF e cliente/server começa por aí.
Se avaliar só essa parte, que é o mínimo de tudo, já tem diferença.

Quem usa DBF se pergunta como fazem os que usam cliente/servidor, e vice-versa.
O estilo de uso é diferente, não dá pra comparar apenas determinada situação.

É por isso que usar cliente/servidor igual DBF acaba deixando tudo mais lento: acaba juntando as piores partes dos dois.
É repensar sobre como o aplicativo vai trabalhar com o banco de dados.

Firebird no Xharbour

MensagemEnviado: 06 Out 2016 21:41
por Hasse
Boa noite colegas.

Uso a IDE do Roberto Lopez, compilando com o Harbour 3.2.0, com MingW.

O teste de compilação acusam erro de falta das funções:
hbmk2: Dica: Adicionar op‡Æo 'hbfbird.hbc' faltando nas fun‡äes: FBClose(),
FBFree(), FBGetData(), FBFetch(), FBQuery(), FBStartTransaction(),
FBConnect()


As INCLUDES estão assim:
#include "MINIGUI.CH"
#include "dbinfo.ch"
#include "error.ch"
#include "hbrddsql.ch"
#include "firebird.ch"
#include "common.ch"
#include "Fileio.ch"


Na pasta do PRG tem:
fbclient.dll
firebird.ch
fbclient.lib
firebird.lib

Imagino que estas funções estão dentro de uma das lib's. Elas estão na pasta mas parece que não são assumidas ou não estão do formato adequado.
Onde devem estar estas LIB's ?

Entretanto, observo que as LIB's do Harbour possuem sufixo ".a" - ???????????? -

Firebird no Xharbour

MensagemEnviado: 07 Out 2016 17:49
por Hasse
Boa tarde colegas.

Testei compilar com xHarbour e passou. Gerou o executável.
   ? FBCreateDB( cServer + cDatabase, cUser, cPass )
   ? FBCreateDB( "G:\Dev2\DentalOff\Small.gdb","SYSDBA","masterkey" )
A linha acima retornou "0" (zero)

   db  := FBConnect( cBanco, "sysdba", "masterkey" )
   db  := FBConnect( "G:\Dev2\DentalOff\Small.gdb", "SYSDBA", "masterkey" )
A linha acima retornou "0x00000001"

   trans    := FBStartTransaction( db )
A linha acima aborta o executável, com a mensagem do Windows:

Arquivos que ajudam a descrever o problema:
C:\Users\Padrao\AppData\Local\Temp\WER8AAA.tmp.WERInternalMetadata.xml
C:\Users\Padrao\AppData\Local\Temp\WERAAA6.tmp.appcompat.txt
C:\Users\Padrao\AppData\Local\Temp\WERAB14.tmp.mdmp

Leia nossa declaração de privacidade online:
http://go.microsoft.com/fwlink/?linkid= ... cid=0x0416

Se a declaração de privacidade online não estiver disponível, leia nossa declaração de privacidade offline:
C:\Windows\system32\pt-BR\erofflps.txt

Firebird no Xharbour

MensagemEnviado: 15 Out 2016 15:59
por Hasse
Boa tarde colegas.

Consegui dominar boa parte da conexão, criar tabelas, ler e gravar tabelas. Mas não consigo gravar dados numéricos contidos em variável dinâmica.
Exemplo:
tpm   := FBQuery( db, "CREATE TABLE Teste_FB( COD int, CLIENTE char(20), CIDADE char(25) )", nDialect, trans )
....
trans := FBStartTransaction( db )
FOR xx1 = 1 TO 10000
   cd1 := "1" + strzero( xx1, 09 )
   cd2 := "2" + strzero( xx1, 19 )
   FBExecute( db, "insert into Teste_FB(CLIENTE, CIDADE) values( '&cd1', '&cd2')", nDialect, trans )
NEXT xx1
FBCommit( trans )
Este PRG acima funciona corretamente, gravando os conteúdos das variáveis contendo string cd1 e cd2.

Testei, uma por uma, as linhas abaixo para gravar dado numérico contido na variável xx1:
   FBExecute( db, "insert into Teste_FB(COD) values( xx1 )", nDialect, trans )
   FBExecute( db, "insert into Teste_FB(COD) values( 'xx1' )", nDialect, trans )
   FBExecute( db, "insert into Teste_FB(COD) values( &xx1 )", nDialect, trans )
   FBExecute( db, "insert into Teste_FB(COD) values( '&xx1' )", nDialect, trans )
E nenhuma funciona.

Como se faz para contornar este problema ?

Firebird no Xharbour

MensagemEnviado: 15 Out 2016 17:50
por tonicm
Tentar da seguinte forma:

FBExecute( db, "insert into Teste_FB(COD) values( "+Transform(xx1, "@E ######.##")+" )", nDialect, trans )

ou

FBExecute( db, "insert into Teste_FB(COD) values( "+AllTrim(Str(xx1))+" )", nDialect, trans )


O que está dentro do transform pode ser mudado conforme for o caso.

Firebird no Xharbour

MensagemEnviado: 15 Out 2016 19:03
por Hasse
Boa noite.

Então pelo que estou entendendo, mesmo que o campo seja int, smallint, ou bigint, o valor gravado deverá ser sempre string ?

Devo sempre transformar o valor numérico em string.

Não é como no DBF que temos campo numérico e grava-se um número.

Firebird no Xharbour

MensagemEnviado: 16 Out 2016 08:34
por Hasse
Bom dia TONICM.

A tua sugestão não funcionou.

Firebird no Xharbour

MensagemEnviado: 16 Out 2016 13:45
por tonicm
Tentar assim:

FBExecute( db, "insert into Teste_FB (COD) VALUES( '"+Transform(xx1, "######")+"' )", nDialect, trans )


Ou assim:
FBExecute( db, "insert into Teste_FB (COD) VALUES( "+Transform(xx1, "######")+" )", nDialect, trans )


Testei no meu PC em MySql e funcionou bem.

Firebird no Xharbour

MensagemEnviado: 16 Out 2016 15:09
por filizola
tentou assim:

FOR xx1 = 1 TO 10000
cd1 := "1" + strzero( xx1, 09 )
cd2 := "2" + strzero( xx1, 19 )
*-----------------
FBExecute( db, "insert into Teste_FB(COD,CLIENTE, CIDADE) values(xx1,&cd1.,&cd2.')", nDialect, trans )
*-----------------
NEXT xx1

Firebird no Xharbour

MensagemEnviado: 16 Out 2016 19:13
por Hasse
Sim, já tentei esta opção também.

Abaixo todas as opções que já testei:
FBExecute( db, "insert into Teste_Dbas(COD) values( xx1 )", nDialect, trans )
FBExecute( db, "insert into Teste_Dbas(COD) values( 'xx1' )", nDialect, trans )
FBExecute( db, "insert into Teste_Dbas(COD) values( &xx1 )", nDialect, trans )
FBExecute( db, "insert into Teste_Dbas(COD) values( '&xx1' )", nDialect, trans )
FBExecute( db, "insert into Teste_Dbas(COD) values( (xx1) )", nDialect, trans )
FBExecute( db, "insert into Teste_Dbas(COD) values( (&xx1) )", nDialect, trans )
FBExecute( db, "insert into Teste_Dbas(COD) values( '(&xx1)' )", nDialect, trans )
FBExecute( db, "insert into Teste_Dbas(COD) values( Str(xx1) )", nDialect, trans )
FBExecute( db, "insert into Teste_Dbas(COD) values( 'Str(xx1)' )", nDialect, trans )
FBExecute( db, "insert into Teste_Dbas(COD) values( 'Alltrim(Str(xx1))' )", nDialect, trans )


O interessante é que funciona com um número fixo na linha:
FBExecute( db, "insert into Teste_Dbas(COD) values( 1 )", nDialect, trans )
FBExecute( db, "insert into Teste_Dbas(COD) values( 2 )", nDialect, trans )
FBExecute( db, "insert into Teste_Dbas(COD) values( 3 )", nDialect, trans )
FBExecute( db, "insert into Teste_Dbas(COD) values( 100 )", nDialect, trans )
FBExecute( db, "insert into Teste_Dbas(COD) values( 155 )", nDialect, trans )

Porém assim não dá para desenvolver um programa minimamente eficiente.

Ou tem alguma opção que funcione ou tem um bug na biblioteca FB do Firebird.

Lembrando que o mesmo problema acontece com a biblioteca RDDINFO()

Em último caso preciso voltar à biblioteca ADO.

Eu estava e ainda estou inclinado pela biblioteca FB do Firebird pois ela não necessita do ODBC e nem de outra biblioteca intermediária, mas se não houver outro jeito este fato me levará a retornar ao ADO.

Firebird no Xharbour

MensagemEnviado: 16 Out 2016 19:50
por tonicm
O valor a gravar no campo COD tem de estar fora das aspas:

Teu teste:
FBExecute( db, "insert into Teste_Dbas(COD) values( 'Alltrim(Str(xx1))' )", nDialect, trans )

Minha forma:
FBExecute( db, "insert into Teste_Dbas(COD) values( "+Alltrim(Str(xx1))+" )", nDialect, trans )

Firebird no Xharbour

MensagemEnviado: 16 Out 2016 20:27
por janio
Um chute:

xx1 ta declarada como variável LOCAL? Experimente coloca-la como PRIVATE!

Jânio

PS: Uso mediator+mysql e numa situação parecida não consigo usar variável local

Firebird no Xharbour

MensagemEnviado: 16 Out 2016 20:40
por Hasse
PERFEITO, meu caro TONICM. OBRIGADO.

Perdão, eu não notei este 'pequeno' detalhe na tua postagem anterior, aquela de ontem, onde já tinha esta instrução.

Agora preciso de mais 2 detalhes:

1)-A lista completa das Funções e Comandos da biblioteca FB e sua respectiva sintaxe.

2)-A lista com a descrição dos Erros retornados.


Onde eu consigo estes documentos ? Já pesquisei no site do Firebird, mas lá não qualquer menção à estas funções.

Firebird no Xharbour

MensagemEnviado: 18 Out 2016 16:48
por tonicm
"For full firebird documentation look at:"

https://github.com/harbour/core/tree/master/contrib/hbfbird