"Hummm.... não pode mudar o assunto pra letodbf, mas pra essa LIB pode...."
"Fico imaginando se a RDDSQL ou similares tiram proveito disso ao trabalhar igual DBF...."
Foi você mesmo quem sugeriu a mudança de assunto...
"Comparem o fonte anterior com o uso do ADO."
Comparando sem qualquer tipo de verificação de erros, como está no exemplo em ADO.
Criar conexão:
hDBD := DBD_NEW(DBD_MYSQL_DRIVER)
DBD_OPEN( hDBD, sCONN )
Buscar informações:
#define FIELD_INDEX_CODIGO 1
#define FIELD_INDEX_NOME 2
hDBD_RES := DBD_QUERY( hDBD, "SELECT CODIGO, NOME FROM CLIENTES ORDER BY NOME" )
If ( hDBD_RES != NIL )
While((hDBD_ROW := DBD_FETCH_ROW( hDBD, hDBD_RES )) != NIL)
aROW := DBD_ROW_ARRAY( hDBD, hDBD_ROW )
? aROW[ FIELD_INDEX_NOME ]
Enddo
Endif
Incluir:
DBD_EXEC( hDBD, "INSERT INTO CLIENTES ( CODIGO, NOME ) VALUES ( 10, 'TESTE' )" )
alterar:
DBD_EXEC( hDBD, "UPDATE CLIENTES SETCODIGO=11, NOME='novo teste' WHERE CODIGO=10" )
excluir:
DBD_EXEC( hDBD, "DELETE FROM CLIENTES WHERE CODIGO=10" )
criar tabela (comando parcial):
DBD_EXEC( hDBD, "CREATE TABLE CLIENTES ( CODIGO INT(11) INCREMENTAL, NOME VARCHAR(50) " )
"Como eu já disse antes, se quer aprender a trabalhar com SQL use ADO."
Para se trabalhar com SQL não precisa de ADO. ADO só roda no "ruindows", usa objetos OLE e parece-me que precisa de ODBC.
A HBDBD roda 100% nativo, usando comunicação direta, sem quaisquer traduções.
É multiplataforma, roda em Windows, Linux, FreeBSD, MacOS, enfim, onde se puder compilar um código 100%
ANSI C, até no Android. Foi feita para desempenho máximo, performance e é otimizada para usar somente recursos eficientes do Harbour, tais como arrays e variáveis simples, que são rápidos e leves, ocupando pouca memória.
"ADO tem que reescrever tudo?
Na LIB apresentada, parece que o fonte fica uma merd... não se entende nada, e depois o fonte não serve pra nada.
Já com ADO... tudo vai ser aproveitado... até mesmo pra outra linguagem de programação."
Se o código já funciona para DBF, então terá que ser reescrito para funcionar com SQL, tanto com ADO, como com a HBDBD, ou com qualquer outra lib ou RDD.
"Não vi a LIB fazer nada disso, pelo contrário, só complicou, vai obrigar a aprender a LIB enquanto poderia estar aprendendo o que interessa."
Acho que o meu exemplo pegou pesado. Realmente é muita coisa para se entender de uma vez só.
A parte complicada ali, se chama "PREPARED QUERIES".
sSQL := "INSERT INTO table1 (codig, name, datecreate, active) VALUES ($1, $2, $3, $4);"
hDBD_PREP := DBD_PREPARE_NEW( hDBD, sSQL, "insert_table1", 4)
If ( hDBD_PREP != NIL )
aROW[1] := NIL // Pula _dbd_id
aROW[2] := "TESTE1"
aROW[3] := CtoD("31/12/2019")
aROW[4] := "Y"
DBD_BIND_ARRAY( hDBD, hDBD_PREP, aROW )
DBD_PEXEC( hDBD, hDBD_PREP, aROW )
Endif
Ou assim:
sSQL := "INSERT INTO table1 (codig, name, datecreate, active) VALUES ($1, $2, $3, $4);"
hDBD_PREP := DBD_PREPARE_NEW( hDBD, sSQL, "insert_table1", 4)
If ( hDBD_PREP != NIL )
aROW[1] := NIL // Pula _dbd_id
aROW[2] := "TESTE1"
aROW[3] := CtoD("31/12/2019")
aROW[4] := "Y"
DBD_BIND_ARRAY( hDBD, hDBD_PREP, aROW )
DBD_PEXEC( hDBD, hDBD_PREP, aROW )
aROW[2] := "TESTE2"
aROW[3] := CtoD("31/12/2020")
aROW[4] := "N"
DBD_BIND_ARRAY( hDBD, hDBD_PREP, aROW )
DBD_PEXEC( hDBD, hDBD_PREP, aROW )
Endif
Para quem não sabe, se não filtrar toda e quaisquer entradas vindas diretamente do usuário, corre-se o risco de uma injeção de SQL, permitindo coisas como ";DROP DATABASE dbNome;".
Nos exemplos acima, não tem como isso acontecer, porquê, não importa o que o usuário digitou e foi parar nas variáveis, o SGDB vai receber tudo escapado e controlado.
"Mas se quiser, pode testar minha classe pra ADO.
Talvez goste dela, talvez não, o único jeito de saber é se testar, ou se der uma olhada.
Mas... NÃO precisa dela pra trabalhar com ADO, também corre o risco de desaprender com ela."
Não preciso de ADO, utilizo comunicação direta, nativa, compilada e rodando a 1000%, que deixa qualquer conexão OLE no chinelo.
"Uma dica pro seu fonte:
Se adicionar/remover algum campo no banco de dados, o fonte já era, vai ser um grande problema fazer a correção de todos os locais que gravam alguma coisa.
Melhor fazer pelo nome."
Não obrigado. Mais overhead desnecessário. Prefiro usar constantes, que são extremamente rápidas e de fácil manutenção, basta localizá-las em um arquivo include ".ch":
#define FIELD_INDEX_UID 1
#define FIELD_INDEX_NAME 2
#define FIELD_INDEX_DATECREATE 3
#define FIELD_INDEX_ACTIVE 4
aROW[FIELD_INDEX_UID] := NIL // Pula _dbd_id
aROW[FIELD_INDEX_NAME] := 1
aROW[FIELD_INDEX_DATECREATE] := CtoD("31/12/2019")
aROW[FIELD_INDEX_ACTIVE] := "Y"
DBD_BIND_ARRAY( hDBD, hDBD_PREP, aROW )
Para cada chamada QueryAdd( "SFCNPJ", cCnpj ), é feito um retrabalho absurdo para se localizar o campo pelo
nome. Como disse a lib é voltada para desempenho, performance, nada que possa criar lentidão desnecessária.
Enfim, não vejo nada de bom nessa ADO, somente desvantagens, só roda no ruindows, usa OLE, usa ODBC.
Pra usar HBDBD, terá que mexer no código, infelizmente sim. Terá que aprender algumas funções novas, infelizmente sim, mas são todas de fácil compreensão e não muda o conhecimento de SQL, pelo contrário, enfatizam a SQL.
Com ela têm-se acesso a múltiplos bancos de dados, utilizando-se SQL, com performance.
Agora poderia-se criar uma API SQL de Banco de Dados, que poderia ser seguida por todas as RDD, como existe para o DBF, seria ótimo e muito bom para os usuários, que poderiam criar um fonte somente e utilizar com qualquer lib, inclusive a HBDBD. Se essa API SQL for criada, certamente a HBDBD irá adotá-la, até lá, infelizmente, tenho que utilizar a API atual.