Dúvida com ENDTEXT

Projeto [x]Harbour - Compilador de código aberto compatível com o Clipper.

Moderador: Moderadores

Avatar do usuário
Vlademiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 752
Registrado em: 11 Jul 2005 02:46

Dúvida com ENDTEXT

Mensagem por Vlademiro »

Olá a todos

Criei um comando EXEC SQL para meus aplicativos. Com ele espero deixar mais claro comandos que são muito grandes e que ocupam muitas linhas.

mas não traduzi o #pragma __endtext

Um exemplo

Código: Selecionar todos


#xcommand END EXEC SQL [MESSAGE TO <cMessage>][ TO <lRet>] => [<lRet>:=] __VLJ_OSQL__:exec([@<cMessage>]);
//#xcommand END EXEC SQL => #pragma __endtext;__VLJ_OSQL__:exec()

...
...
...

  SQL EXEC CONNECT BY cStringADOSQL PARAMETERS hb_RandomInt( 1000, 2000 ) , 'USUÁRIO 12' CODE
    
        INSERT INTO EMP ( EMPNO, ENAME ) VALUES ( %s , '%s' )
    #pragma __endtext //  <=======   Quero incluir na definição de END EXEC
    END EXEC SQL MESSAGE TO cMessage TO lRet
    IF lRet 
        ? "Sucesso"
    ELSE
        ? "Erro"
        ? cMessage
    ENDIF 

Encontrei esse link com as definições do ENDTEXT

https://github.com/harbour/core/blob/ma ... pragma.txt
Lá está assim
#xcommand ENDTEXT => #pragma __endtext

Tentei fazer assim

#xcommand END EXEC SQL => #pragma __endtext;__VLJ_OSQL__:exec()


Mas não funciona. Alguém poderia me ajudar ?

Do jeito que está já funciona, espero evoluir esse mmodelo para retornar um array ou um dbf virtual com os resultados de um select complexo.
código fonte está anexado. Banco de dados de arquivos MDB também (usado neste exemplo).
execsql.zip
(19.65 KiB) Baixado 51 vezes
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Dúvida com ENDTEXT

Mensagem por JoséQuintas »

Eu pensaria melhor no conjunto.

Sei lá... só pra dar uma idéia...

Código: Selecionar todos

LOCAL cnSQL := ADOClass():New( AppConexao() )

WITH OBJECT cnSQL
   :QueryCreate()
   :QueryAdd( "EMPNO", nIdEmpresa )
   :QueryAdd( "ENAME", cNomeEmpresa )
   :QueryExecuteInsert( "EMP" )
ENDWITH
Conforme a lista de campos, se for gigante, mais fácil conferir da forma acima do que pelo comando.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Dúvida com ENDTEXT

Mensagem por JoséQuintas »

Naquele fonte, até confundi sobre o que estava sendo inserido.
Só um aproximado.

Código: Selecionar todos

REQUEST HB_CODEPAGE_PTISO

PROCEDURE MAIN

   LOCAL cnSQL := ADOClass():New( AppConexao() )

   hb_cdpSelect( "PTISO" )
   
 
   WITH OBJECT cnSQL
      :QueryCreate()
      :QueryAdd( "EMPNO", hb_RandomInit( 1000, 2000 ) )
      :QueryAdd( "ENAME", "USUARIO 12" )
      :QUeryExecuteInsert( "EMP" )
   ENDWITH
    
   RETURN
A conexão:

Código: Selecionar todos

STATIC FUNCTION AppConexao( cString )

   LOCAL oConexao, cDatabase := "sistemas33.mdb"
   
   oConexao := win_oleCreateObject( "ADODB.Connection" )
   oConexao:ConnectionString := "DBQ=" + hb_FNameMerge( hb_DirBase(), cDatabase ) + ";Driver={Microsoft Access Driver (*.mdb)}"

   RETURN oConexao
e a classe

Código: Selecionar todos

CREATE CLASS ADOClass
   VAR cSQL
   VAR cnSQL
   VAR aList
   METHOD New( cnSQL )
   METHOD Open()                        INLINE ::cnSQL:Open()
   METHOD Close()                       INLINE ::cnSQL:Close()
   METHOD Execute( cSQL )               INLINE ::cnSQL:Execute( iif( cSQL == NIL, ::cSQL, cSQL ) )
   METHOD QueryCreate()                 INLINE ::aList := {}  
   METHOD QueryAdd( a, b )              INLINE Add( ::aList, { a, b } )
   METHOD QueryExecuteInsert( cTable )
   ENDCLASS

METHOD New( cnSQL ) CLASS ADOClass

   ::cnSQL := cnSQL
   RETURN SELF

METHOD QueryExecuteInsert( cTable ) CLASS ADOClass

   LOCAL cSQL
   
   cSQL := "INSERT INTO " + cTable + " ( "
   FOR EACH oElement IN ::aList
      cSQL += oElement[ 1 ] + iif( oElement:__EnumIsLast(), "", ", " )
   NEXT
   cSQL += " ) VALUES ( "
   FOR EACH oElement IN ::aList
      cSQL += ValueSQL( oElement[ 2 ] ) + iif( oElement:__EnumIsLast(), "", ", " )
   NEXT
   cSQL += " )"
   
   RETURN ::Execute( cSQL )
   
FUNCTION ValueSQL( xValue ) CLASS ADOClass

   DO CASE
   CASE ValType( xValue ) == "N"; RETURN NTos( xValue )
   CASE ValType( xValue ) == "D" .AND. Empty( xValue ); RETURN "NULL"
   CASE ValType( xValue ) == "D"; RETURN ['] + Transform( Dtos( xValue ), "@R 9999-99-99" ) + [']
   ENDCASE
   
   RETURN ['] + xValue + [']
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
Vlademiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 752
Registrado em: 11 Jul 2005 02:46

Dúvida com ENDTEXT

Mensagem por Vlademiro »

A ideia central é conseguir simplificar a criação de Querys complexas, eu nem cheguei a concluir porque eu tive problemas
com esse #pragma para finalizar o comando.

Eu já trabalhei com vários bancos ao longo dos anos, uma das minhas piores experiências foi com umas querys gigantes que tomavam
( sem exagero algum ) umas cinco folhas de papel. O servidor na época era um SQL Server 2000 (um ótimo servidor de banco por sinal),
e essas querys eram de uma empresa que prestava serviços para o local onde eu trabalhava.

Quando entrei nessa dita empresa me disseram : "você vai ter que se virar com essas consultas porque nós não vamos mais pagar
treinamento/consultoria para alguém vir aqui lhe ensinar". O problemas com essas querys gigantes, além da falta de documentação, que
era o problema principal, era poder entender ela no meio do código da linguagem usada para consultar elas. O sistema era em Delphi, mas
a gente não tinha os fontes, daí fizeram as consultas em perl. Uma outra curiosidade era que na época a Microsoft não facilitava para
o Linux e até para acessar o banco via Linux tinha que recorrer ao driver do antigo dono do SQL Server, que era a Sybase (A Microsoft comprou
o SQL Server, ou a maior parte dele, da Sybase para fazer frente a Oracle, que ameaçava o mercado de bancos corporativos médios e pequenos).

Mas voltando ao assunto, a ideia central é Querys gigantes sem ter que misturar ao código fonte da linguagem do aplicativo como comumente
é feito.

Da forma como eu fiz tem que melhorar um pouco, tem que criar tags mais claras, porque somente o %s do hb_StrFormat confunde o leitor.

Algo como :

Código: Selecionar todos

EXEC SQL 
PARAMETERS
   :cNome := FIELD->NOME_CLIENTE
   :nVal := FIELD->SALARIO

   ... Mais parâmetros

CODE

     SELECT GIGANTE DE MUUITAS LINHAS
           ...
     WHERE nome like '%:cNome%' and salario >= :nVal

END EXEC SQL

Penso também na possibilidade de "quebrar" o SQL em partes deixando o principal de um jeito e acrescentando as condições
de filtro conforme o usuário for selecionando. Tipo aqueles relatórios que alguém executa a mesma query mas acrescenta
um WHERE final diferente de acordo com o filtro solicitado.

Enquanto estava digitando surgiram outras ideias.
Avatar do usuário
RamonXHB
Usuário Nível 3
Usuário Nível 3
Mensagens: 159
Registrado em: 03 Mar 2007 14:55

Dúvida com ENDTEXT

Mensagem por RamonXHB »

Eu também uso assim, o where é montado de acordo com o que o usuário selecionar e depois é adicionado ao corpo principal da query.
Essa idéia facilita bastante para entender o que a query faz, depois de ficar muito tempo sem precisar mexer no programa.
Não tem aquela história de ler e reler até entender o que foi feito.
Ramon A. Körber Jr.
Harbour 3.2 MiniGUI Extended Edition
xDevStudio v0.70 - BCC 5.82 - Lazarus FreePascal
Firebird
AdoDB - ODBC
Windows - Linux
Linux User Number 404280
MSN - ramon15061959@hotmail.com
Skype - ramon15061959
ICQ - UIN 82580595
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Dúvida com ENDTEXT

Mensagem por JoséQuintas »

É, mas precisa tomar cuidado pra ver se está facilitando ou complicando, porque no primeiro só vi complicação.

Pensei numa coisa agora..... de repente pode facilitar geral

Vou fazer testes primeiro.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Dúvida com ENDTEXT

Mensagem por JoséQuintas »

Uia

Código: Selecionar todos

SELECT 1 AS p1, 2 AS p2, 3 AS p3, 4 AS p4, 5 AS p5 

Código: Selecionar todos

     SELECT GIGANTE DE MUUITAS LINHAS
           ...
    INNER JOIN ( TABELAVARIAVEIS ) AS VARIAVEL ON 1=1
     WHERE NOME LIKE CONCAT( '\'', '%', variavel.p1, '%','\%' ) and salario >= variavel.p2
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Dúvida com ENDTEXT

Mensagem por JoséQuintas »

SET @p1 = 'JUCA'
SET @p2 = 2000

SELECT GIGANTE DE MUUITAS LINHAS
...
WHERE NOME LIKE CONCAT( '\'', '%', @p1, '%','\%' ) and salario >= @p2
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
Vlademiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 752
Registrado em: 11 Jul 2005 02:46

Dúvida com ENDTEXT

Mensagem por Vlademiro »

Bem vindo ao mundo dos subselects.

Uma dica que recebi e repasso:

Descubra o que a query faz, o objetivo dela. Depois comece tentando entender os selects mais internos. Só depois passe para os de fora.
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Dúvida com ENDTEXT

Mensagem por JoséQuintas »

Vai ter que achar seu ponto de equilíbrio, entre complicar o fonte, ou complicar o comando SQL.
De repente, mudar um pouco em cada lado pode deixar menos complicado.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
Vlademiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 752
Registrado em: 11 Jul 2005 02:46

Dúvida com ENDTEXT

Mensagem por Vlademiro »

Meu Exec sql foi pro espaço. Não tem como substituir aquele endtext...
Avatar do usuário
Vlademiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 752
Registrado em: 11 Jul 2005 02:46

Dúvida com ENDTEXT

Mensagem por Vlademiro »

Vou ficar só na montagem da query, deixo a execução para outra rotina
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Dúvida com ENDTEXT

Mensagem por JoséQuintas »

Sei lá... enfiar TEXT/ENDTEXT no meio parece pior

Código: Selecionar todos

   WITH OBJECT cnSQL
      :cSQL := "SELECT IDPEDIDO, PDDATEMI, PDCADASTRO, PDVALNOT," + ;
         " PDVENDEDOR, PDTRANSA, PDPEDCLI, PDCONF, JPVENDEDOR.VDCOMISSAO"
      IF nOpcDetalhe == 3 .OR. nOpcLayout == 2
         :cSQL += " PDOBS,"
      ENDIF
      :cSQL += " JPNOTFIS.NFNOTFIS," + ;
         " JPTRANSA.TRDESCRI, " + ;
         " JPCADASTRO.CDNOME, JPCADASTRO.CDAPELIDO," + ;
         " JPVENDEDOR.VDCOMISSA" + ;
         " FROM JPPEDIDO" + ;
         " LEFT JOIN JPNOTFIS ON JPNOTFIS.NFPEDIDO = JPPEDIDO.IDPEDIDO" + ;
         " LEFT JOIN JPTRANSA ON JPTRANSA.IDTRANSA = JPPEDIDO.PDTRANSA" + ;
         " LEFT JOIN JPCADASTRO ON JPCADASTRO.IDCADASTRO = JPPEDIDO.PDCADASTRO" + ;
         " LEFT JOIN JPVENDEDOR ON JPVENDEDOR.IDVENDEDOR = JPPEDIDO.PDVENDEDOR" + ;
         " WHERE 1=1"
      IF nOpcTransacao == 2
         :cSQL += " AND PDTRANSA = " + NumberSQL( nIdTransacaoIni )
      ENDIF
      IF nOpcVendedor == 2
         :cSQL += " AND PDVENDEDOR = " + NumberSQL( nIdVendedorIni )
      ENDIF
      IF nOpcConfirmado == 2
         :cSQL += " AND PDCONF = 'S'"
      ELSEIF nOpcConfirmado == 3
         :cSQL += " AND PDCONF <> 'S'"
      ENDIF
      IF nOpcDatEmi == 2
         :cSQL += " AND PDDATEMI BETWEEN CAST( " + DateSQL( dEmissaoIni ) + " AS DATE ) AND CAST( " + DateSQL( dEmissaoFim ) + " AS DATE )"
      ENDIF
      IF nOpcNFEmitida == 2
         :cSQL += " AND NOT JPNOTFIS.NFNOTFIS IS NULL"
      ELSEIF nOpcNFEmitida == 3
         :cSQL += " AND JPNOTFIS.NFNOTFIS IS NULL"
      ENDIF
      IF nOpcCadastro == 2
         :cSQL += " AND PDCADASTRO = " + NumberSQL( nIdCadastroIni )
      ENDIF
      IF ! Empty( m_NaoSai )
         :cSQL += " AND NOT PDCADASTRO IN ( " + m_NaoSai + " )"
      ENDIF
      IF ! Empty( mFiltro )
         :cSQL += " AND ( " + mFiltro + " )"
      ENDIF
      :Execute()
Só curiosidade: WHERE 1 = 1 é pra não fazer nada, só serve de imenda para os AND, evitando complicação
WHERE 1 = 1 AND date between ...
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Dúvida com ENDTEXT

Mensagem por JoséQuintas »

E se pegar um comando deste.....
O comando por si só é complicado, nada que faça vai deixar visível do que se trata, nem text/endtext, nem outra coisa.

Código: Selecionar todos

      :cSQL := ;
         "SELECT " + ;
            " IDESTOQUE, ESPRODUTO, ESDATLAN, ESCADASTRO, ESCFOP, ESPEDIDO, ESTIPLAN, " + ;
            " IF( JPNFEKEY.KKCHAVE IS NULL, LPAD( RIGHT( TRIM( ESNUMDOC ), 7 ), 7, '0' ), LPAD( '', 7, ' ' ) ) AS NUMDOC," + ;
            " ESQTDE  * IF( JPITEM.IEQTDCOM < 1, 1, JPITEM.IEQTDCOM ) AS QTDE," + ;
            " ESQTDE * ESVALOR AS VALOR," + ;
            " JPITEM.IEUNID AS UNIDADE, JPITEM.IEANP AS ANPPRO, JPITEM.IEDESCRI AS ITENOME, " + ;
            " IF( TABANPINS.AIANP IS NULL OR JPANPOPE.AOANPREG = '1022002', JPCADASTRO.CDCNPJ, LPAD( '', 14, '0' ) ) AS CADCNPJ, " + ;
            " JPCADASTRO.CDCIDADE AS CADCIDADE, JPCADASTRO.CDUF AS CADUF, JPCADASTRO.CDNOME AS CADNOME," + ;
            " TABCIDADE.CIIBGE AS IBGE," + ;
            " IF( TABANPINS.AIANP IS NULL OR JPANPOPE.AOANPREG = '1022002', TABANPLOC.ALANP, LPAD( '', 7, '0' ) ) AS ANPLOC," + ;
            " IF( TABANPINS.AIANP IS NULL OR JPANPOPE.AOANPREG = '1022002', LPAD( '', 7, '0' ), TABANPINS.AIANP ) AS ANPINS," + ;
            " IF( TABANPINS.AIANP IS NULL, LPAD( '',10,' '), TABANPAGE.AAANP ) AS ANPAGE," + ;
            " IF( TABANPINS.AIANP IS NULL OR JPANPOPE.AOANPREG = '1022002', TABANPATI.ATCNAE, LPAD( '', 5, '0' ) ) AS ANPATI," + ;
            " IF( TABANPINS.AIANP IS NULL, IF( JPCADASTRO.CDCNAE = '9999999', JPANPOPE.AOANPOUT, JPANPOPE.AOANPNREG ), JPANPOPE.AOANPREG ) AS ANPOPE, " + ;
            " JPNFEKEY.KKCHAVE AS NFEKEY " + ;
         " FROM JPESTOQUE" + ;
            " LEFT JOIN JPITEM ON JPITEM.IDPRODUTO = JPESTOQUE.ESPRODUTO" + ;
            " LEFT JOIN JPCADASTRO ON JPCADASTRO.IDCADASTRO = JPESTOQUE.ESCADASTRO" + ;
            " LEFT JOIN ( SELECT DISTINCT CIIBGE, CIUF, CINOME FROM JPCIDADE ) AS TABCIDADE " + ;
               " ON JPCADASTRO.CDUF = TABCIDADE.CIUF AND LEFT( JPCADASTRO.CDCIDADE, 20 ) = LEFT( TABCIDADE.CINOME, 20 )" + ;
            " LEFT JOIN " + ;
               " ( SELECT DISTINCT ALIBGE, ALANP FROM JPANPLOC WHERE LENGTH( ALVALATE ) < 1 ) AS TABANPLOC" + ;
               " ON TABANPLOC.ALIBGE = TABCIDADE.CIIBGE " + ;
            " LEFT JOIN " + ;
               " ( SELECT DISTINCT AICNPJ, AIANP FROM JPANPINS WHERE LENGTH( AIVALATE ) < 1 ) AS TABANPINS" + ;
               " ON TABANPINS.AICNPJ = IF( LENGTH( JPCADASTRO.CDCNPJ ) = 18," + ;
                  " CONCAT( SUBSTR( JPCADASTRO.CDCNPJ, 1, 2 ), SUBSTR( JPCADASTRO.CDCNPJ, 4, 3 )," + ;
                  " SUBSTR( JPCADASTRO.CDCNPJ, 8, 3 ), SUBSTR( JPCADASTRO.CDCNPJ, 12, 4 )," + ;
                  " SUBSTR( JPCADASTRO.CDCNPJ, 17, 2 ) ), 'X' ) " + ;
            " LEFT JOIN " + ;
               " ( SELECT DISTINCT AACNPJ, AAANP FROM JPANPAGE WHERE LENGTH( AAVALATE ) < 1 ) AS TABANPAGE " + ;
               " ON TABANPAGE.AACNPJ = IF( LENGTH( JPCADASTRO.CDCNPJ ) = 18," + ;
                  " CONCAT( SUBSTR( JPCADASTRO.CDCNPJ, 1, 2 ), SUBSTR( JPCADASTRO.CDCNPJ, 4, 3 ), SUBSTR( CDCNPJ, 8, 3 ) ), 'X' ) " + ;
            " LEFT JOIN JPANPOPE ON JPANPOPE.AOCFOP = JPESTOQUE.ESCFOP" + ;
            " LEFT JOIN " + ;
               " ( SELECT DISTINCT ATCNAE FROM JPANPATI WHERE LENGTH( ATVALATE ) < 1 ) AS TABANPATI" + ;
               " ON TABANPATI.ATCNAE = Left( JPCADASTRO.CDCNAE, 5 )" + ;
            " LEFT JOIN JPPEDIDO ON JPPEDIDO.IDPEDIDO = JPESTOQUE.ESPEDIDO" + ;
            " LEFT JOIN JPNOTFIS ON JPNOTFIS.NFPEDIDO = JPPEDIDO.IDPEDIDO" + ;
            " LEFT JOIN JPNFEKEY ON JPNFEKEY.KKMODFIS = '55'" + ;
               " AND JPNFEKEY.KKNOTFIS = IF( JPNOTFIS.NFNOTFIS IS NULL, JPESTOQUE.ESNUMDOC, JPNOTFIS.NFNOTFIS )" + ;
               " AND IF( JPNOTFIS.NFNOTFIS IS NULL, " + ;
               " JPNFEKEY.KKEMINFE = JPCADASTRO.CDCNPJ AND KKDESNFE = " + StringSQL( jpempresa->emCnpj ) + ", " + ;
               " JPNFEKEY.KKEMINFE = " + StringSQL( jpempresa->emCnpj ) + " )" + ;
            " WHERE " + ;
               " ESDATLAN BETWEEN CAST( " + DateSQL( dDataInicial ) + " AS DATE )" + ;
               " AND CAST( "  + DateSQL( dDataFinal ) + " AS DATE )" + ;
               " AND JPITEM.IEANP IN ( SELECT IDANPPRO FROM JPANPPRO WHERE APISIMP = 'S' )"
      :cSQL += " AND ESQTDE <> 0" + ;
         " ORDER BY ESDATLAN, IDESTOQUE"
      :Execute()
Só se for pra copiar de/para HEIDISQL, de resto não ajuda nada.

As vezes coloco

? :cSQL no fonte, pra poder copiar/colar da tela o comando montado, mas fazer o que....

Criar uma rotina especial pra esse comando, só pra substituir duas variáveis.....
Até parece que deixaria o comando mais simples

" ESDATLAN BETWEEN CAST( " + DateSQL( dDataInicial ) + " AS DATE )" + " AND CAST( " + DateSQL( dDataFinal ) + " AS DATE )" + ;
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Responder