Página 1 de 4

Teste de SQL com DBF

Enviado: 14 Jan 2020 00:57
por JoséQuintas
Infelizmente, não serve como modelo pronto, porque depende dos arquivos, e os arquivos contém informações particulares, então não vou fornecer arquivos.
É apenas pra mostrar possibilidades.

Código: Selecionar todos

#include "inkey.ch"

PROCEDURE Main

   LOCAL oConexao, oRs

   oConexao := ConexaoMySql( "d:\jpa\cordeiro" )
   oConexao:Open()
   SetMode(40,100)
   CLS
   oRs := oConexao:Execute( "SELECT " + ;
      " IDPEDIDO," + ;
      " JPNOTFIS.NFNOTFIS AS NOTFIS, " + ;
      " JPCADASTRO.CDNOME AS CADNOME, " + ;
      " JPFINAN.FIDATVEN AS DATVEN, " + ;
      " JPFINAN.FIVALOR AS VALOR, " + ;
      " JPITPED.IPITEM AS ITEM, " + ;
      " JPITPED.IPVALNOT AS VALNOT," + ;
      " JPITEM.IEDESCRI AS ITEMNOME" + ;
      " FROM JPPEDIDO" + ;
      " LEFT JOIN JPNOTFIS ON JPNOTFIS.NFPEDIDO=JPPEDIDO.IDPEDIDO" + ;
      " LEFT JOIN JPCADASTRO ON JPCADASTRO.IDCADASTRO=JPPEDIDO.PDCLIFOR" + ;
      " LEFT JOIN JPFINAN ON JPFINAN.FIPEDIDO=JPPEDIDO.IDPEDIDO" + ;
      " LEFT JOIN JPITPED ON JPITPED.IPPEDIDO=JPPEDIDO.IDPEDIDO" + ;
      " LEFT JOIN JPITEM ON JPITEM.IDITEM=JPITPED.IPITEM" + ;
      " WHERE PDDATEMI BETWEEN '2019-12-01' AND '2019-12-10'" )
   WITH OBJECT oRs
      DO WHILE ! :Eof()
         ?? oRs:Fields( "IDPEDIDO" ):Value
         ?? oRs:Fields( "NOTFIS" ):Value
         ?? oRs:Fields( "CADNOME" ):Value
         ?? oRs:Fields( "DATVEN" ):Value
         ?? oRs:Fields( "VALOR" ):Value
         ?? oRs:Fields( "ITEM" ):Value
         ?? oRs:Fields( "VALNOT" ):Value
         ?? oRs:Fields( "ITEMNOME" ):Value
         ?
         :MoveNext()
      ENDDO
      :Close()
   ENDWITH
   oConexao:Close()
   Inkey(0)

   RETURN

FUNCTION ConexaoMySql( cPath )

   LOCAL oConexao := win_OleCreateObject( "ADODB.Connection" )

   oConexao:ConnectionString := "Provider=Advantage OLE DB Provider;" + ;
      "Mode=Share Deny None;" + ;
      "Show Deleted Records in DBF Tables with Advantage=False;" + ;
       "Data Source=" + cPath + ";Advantage Server Type=ADS_Local_Server;" + ;
       "TableType=ADS_CDX;Security Mode=ADS_IGNORERIGHTS;" + ;
       "Lock Mode=Compatible;" + ;
       "Use NULL values in DBF Tables with Advantage=True;" + ;
       "Exclusive=No;Deleted=No;"
   oConexao:CursorLocation := 3
   oConexao:CommandTimeOut := 20

   RETURN oConexao
O comando lista os pedidos, já pesquisando no financeiro, cadastro de clientes, itens de pedido, descrição de produtos, notas fiscais e filtro por data.

É direto do DBF !!!

Tive que apagar os índices atuais, porque acusou chave de indexação inválida.
Provavelmente porque não tem Left() ou alguma coisa parecida, mas caso alguém vá usar, trocaria Left() por Substr() e tudo bem.
Como era teste, nem me preocupei, apenas apaguei os CDX.

NÃO consegui fazer com o ODBC 11, deve ser uma string diferente, mas pra teste nem pesquisei, usei o que tinha aqui.

O ODBC que usei foi com meu antigo instalador:
http://www.josequintas.com.br/arquivos/setupjpa.msi

Mas importante:
O instalador instala ODBC ADS, Capicom e MSXML5 - os componentes de NFE
Infelizmente (ou não), ele remove tudo se deinstalar o setupjpa.
Se usa algum deles, fique sabendo que vai precisar reinstalar ao remover o setupjpa.

Quanto ao comando SQL e nomes de campos, só ajustar para seus DBFs.

Teste de SQL com DBF

Enviado: 14 Jan 2020 01:09
por JoséQuintas
Faltou dizer:

Os comandos são compatíveis com SQL server, mas nesse caso ficaram exatamente iguais ao do MySQL, porque não usei nada diferente do padrão comum aos dois.
Aceitou até relacionar campo numérico com campo caractere, igual acontece no MySQL.

Tamanho dos arquivos do teste:
pedidos: 160MB
itens de pedido: 174MB
financeiro: 115MB
nota fiscal: 232MB
itens: 1.3MB

Usei apenas local, coisa de 1 segundo pra mostrar o resultado.
Tem informação desde 2008 até 2020, cerca de 12 anos de movimentação.
SEM ÍNDICES, somente os DBFs !!!

Teste de SQL com DBF

Enviado: 14 Jan 2020 11:32
por Marcos Kieron
mas... ADS já existe a quase 30 anos e somente agora é que você viu isso?

Teste de SQL com DBF

Enviado: 14 Jan 2020 13:32
por JoséQuintas
Marcos Kieron escreveu:mas... ADS já existe a quase 30 anos e somente agora é que você viu isso?
Só repassando pra quem não sabe, e quiser brincar com comandos SQL sem precisar instalar servidor.

Teste de SQL com DBF

Enviado: 15 Jan 2020 11:44
por Marcos Kieron
Entendi, bom eu não uso ADS, sei que é muito rápido, mas sugiro passar direto para SQL, se for algo muito grande um Postgress mas em geral melhor usar MySQL ou MariaDB que vai resolver 99,9999% dos casos.
Se for algo local, então nem perde tempo, o SQLite vai fazer muiiiiiiito e não precisa instalar ou configurar nada, é a melhor opção local.

Teste de SQL com DBF

Enviado: 15 Jan 2020 22:33
por JoséQuintas
Só atualizando informação.
É só instalar o OLEDB e mais nada.
Se Harbour 32 bits, instala o 32 bits.
Em XHarbour... não uso... em Harbour, é só usar win_OleCreateObject() da hbwin e mais nada.

https://devzone.advantagedatabase.com/d ... Product=15

Teste de SQL com DBF

Enviado: 16 Jan 2020 01:44
por JoséQuintas
Pra uso genérico.
Só compilar e baixar o OLEDB do ADS.

Com certeza vai ficar melhor em LIB gráfica, principalmente pra poder digitar um comando de várias linhas.
MemoEdit() não serve porque inclui caracteres especiais, e Picture @S ajuda mas fica ruim pra conferir o comando.

É digitar o comando SQL e aparece o browse com o resultado.
PRA USAR COM DBFS.
test.png
test.zip
(475.09 KiB) Baixado 367 vezes

Teste de SQL com DBF

Enviado: 16 Jan 2020 01:58
por JoséQuintas
ado.png

Teste de SQL com DBF

Enviado: 16 Jan 2020 04:50
por JoséQuintas
Agora com formatação no comando SQL pra ficar no máximo 80 letras por linha
É só pro teste, sem grandes mudanças.
Talvez até o controle multiline da gtwvg fosse melhor, mas.... não tô a fim de mexer nisso.

Totais por cidade
browse.png
test.zip
(476.04 KiB) Baixado 372 vezes
Detalhe do ADS:
Todas as colunas que não são totais, obrigatoriamente precisam aparecer no group by.
Não aceitou duas colunas no left join
Talvez algum detalhe a mais, que só no ADS é necessário.
isso limita, comparado ao MySQL, mas pra aprendizado tá bom, dá pra fazer muita coisa.
Talvez quem mexe com SQL Server saiba, mas pra mim não interessa mais DBF, nem com SQL.

Teste de SQL com DBF

Enviado: 17 Jan 2020 12:25
por Marcos Kieron
Para mim DBF só se não puder alterar para SQL, não vejo vantagem no DBF em nenhum caso possível

Teste de SQL com DBF

Enviado: 17 Jan 2020 21:55
por asimoes
Quintas,

estou usando o seu teste.prg

Neste ponto tem como trazer todas as colunas para a grid sem ficar testando?
Tentei passar um for ... next mais não funcionou provavelmente porque o bloco não aceita variável externa para executar

Código: Selecionar todos

   nQtd := oRs:Fields:Count()
   for i:=0 to nQtd - 1
      AAdd( oTBrowse, { oRs:Fields( i ):Name, { || oRs:Fields( i ):Value } } ) 
   next



        IF nQTD > 0; AAdd( oTBrowse, { oRs:Fields( 0 ):Name, { || oRs:Fields( 0 ):Value } } ) ; ENDIF
         IF nQTD > 1; AAdd( oTBrowse, { oRs:Fields( 1 ):Name, { || oRs:Fields( 1 ):Value } } ) ; ENDIF
         IF nQTD > 2; AAdd( oTBrowse, { oRs:Fields( 2 ):Name, { || oRs:Fields( 2 ):Value } } ) ; ENDIF
         IF nQTD > 3; AAdd( oTBrowse, { oRs:Fields( 3 ):Name, { || oRs:Fields( 3 ):Value } } ) ; ENDIF
         IF nQTD > 4; AAdd( oTBrowse, { oRs:Fields( 4 ):Name, { || oRs:Fields( 4 ):Value } } ) ; ENDIF
         IF nQTD > 5; AAdd( oTBrowse, { oRs:Fields( 5 ):Name, { || oRs:Fields( 5 ):Value } } ) ; ENDIF
         IF nQTD > 6; AAdd( oTBrowse, { oRs:Fields( 6 ):Name, { || oRs:Fields( 6 ):Value } } ) ; ENDIF
         IF nQTD > 7; AAdd( oTBrowse, { oRs:Fields( 7 ):Name, { || oRs:Fields( 7 ):Value } } ) ; ENDIF
         IF nQTD > 8; AAdd( oTBrowse, { oRs:Fields( 8 ):Name, { || oRs:Fields( 8 ):Value } } ) ; ENDIF
         IF nQTD > 9; AAdd( oTBrowse, { oRs:Fields( 9 ):Name, { || oRs:Fields( 9 ):Value } } ) ; ENDIF
         BrowseADO( oRs, oTBrowse )

Teste de SQL com DBF

Enviado: 18 Jan 2020 00:32
por asimoes
Consegui:

Código: Selecionar todos

            WITH OBJECT oRs
               nCol := ( :Fields:Count ) - 1
               FOR i:=0 TO nCol
                  aAdd( oTBrowse, { oRs:Fields( I ):Name, ADORecordSetFieldBlock(oRs, i)} )
               NEXT
               BrowseADO( oRs, oTBrowse )
            END

Teste de SQL com DBF

Enviado: 18 Jan 2020 09:14
por JoséQuintas
Não colocou a solução, mas é de se imaginar.
Isso pode ser útil pra outras coisas não somente pra esse caso.
Até mesmo GET de array, ou um menu em GUI:

Código: Selecionar todos

aList := { "A", "B", "C" }
FOR nCont = 1 TO 3
   DoGet( aList, nCont )
NEXT
READ

FUNCTION DoGet( aList, nItem )
  
   @ Row() + 1, 0 GET aLIst[ nItem ]
 
   RETURN NIL
Qual a diferença?

Se colocar direto na linha do FOR/NEXT não dá certo, porque o valor de nCont não é fixo, parece que vai respeitar o contador, mas na hora do GET o valor é outro.
Já colocando na função, a variável é local, e o valor será fixo.

No codeblock pro ADO é o mesmo esquema.

Código: Selecionar todos

FOR nCont = 1 TO Rs:Fields:Count()
   RsCodeBlock( Rs, nCont - 1 )
NEXT

FUNCTION RsCodeBLock( Rs, nItem )

   RETURN { || Rs:Fields( nItem ):Value }
Só pra comparação com equivalente DBF, que seria o mesmo caso:

clientes->( FieldGet( nItem ) )

RS:Fields( nItem ):Value

Nota:
No caso do GET foi só exemplo, apesar de dar certo, tem alternativa melhor:

Código: Selecionar todos

aList := { "A", "B", "C" } 
FOR EACH oElement IN aList
   @ Row() + 1, 0 GET oElement
NEXT
READ

Teste de SQL com DBF

Enviado: 18 Jan 2020 22:01
por asimoes
Para usar o formato DD/MM/YYYY com o ADS OleDb

Código: Selecionar todos

hDLL := Hb_libLoad( "ace32.dll" )

nStatus := Hb_dynCall( { "AdsSetDateFormat", hDLL, HB_DYN_CALLCONV_STDCALL}, "DD/MM/YYYY" )

Teste de SQL com DBF

Enviado: 19 Jan 2020 10:28
por Marcos Kieron
Fica complicado para usar ADS, creio que é melhor passar direto para um SQL, compensa o esforço