Clipper On Line • Ver Tópico - Sugestão de solução

Sugestão de solução

Discussão sobre SQL

Moderador: Moderadores

 

Sugestão de solução

Mensagempor JoséQuintas » 02 Jul 2021 14:21

STATIC FUNCTION PedidoStatus( nIdPedido, cPedidoStatus, cConfPedido )

   LOCAL cStatus

   DO CASE
   CASE nIdPedido == 0
      cStatus := ""
   CASE cPedidoStatus == "C"
      cStatus := "*CANCELADO*"
   CASE ADORecCount( "JPNOTFIS", "NFPEDIDO = " + NumberSQL( nIdPedido ) ) != 0
      cStatus := "NF.EMITIDA"
   CASE cConfPedido != "S"
      cStatus := "*N/CONFIRMADO"
   OTHERWISE
      cStatus := "FATURAR"
   ENDCASE
   cStatus := Pad( cStatus, 20 )

   RETURN cStatus


Tenho a rotina acima, pensei em fazer no MySQL, mas a primeira tentativa não foi aceita.
Testei na definição de um campo, mas parece que lá é pra DEFAULT e pelo menos no default não aceita um SELECT.i

A possibilidade que vejo seria como STORED FUNCTION ou como um VIEW.

O teste, como comando, foi este:

SELECT 
IF(
( SELECT COUNT(*)
   FROM jpnotfis
   WHERE IDPEDIDO=NFPEDIDO )
<> 0, 'EMITIDA', 'NAO' ) AS STATUS
FROM JPPEDIDO


Como campo calculado, a vantagem seria trazer ponto.
Ou... talvez isso só possa ser feito por comando, e não pelo editor do HeidiSQL.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"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 de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18129
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1215 vezes

Sugestão de solução

Mensagempor alxsts » 02 Jul 2021 16:07

Olá!
JoséQuintas escreveu:Tenho a rotina acima, pensei em fazer no MySQL, mas a primeira tentativa não foi aceita.
Testei na definição de um campo, mas parece que lá é pra DEFAULT e pelo menos no default não aceita um SELECT.i

Não entendi bulhufas do enunciado do problema...

Em todo caso, veja se isto ajuda em alguma coisa:
SELECT 
   CASE WHEN EXISTS
             (SELECT 1 FROM jpnotfis nf
                JOIN JPPEDIDO p
                  ON p.IDPEDIDO = nf.NFPEDIDO
             )
        THEN 'EMITIDA'
        ELSE 'NÃO EMITIDA'
   END AS STATUS

Ou

SELECT
   CASE WHEN EXISTS
             (SELECT 1 FROM jpnotfis nf, JPPEDIDO p
               WHERE p.IDPEDIDO = nf.NFPEDIDO
               LIMIT 1
             )
        THEN 'EMITIDA'
        ELSE 'NÃO EMITIDA'
   END AS STATUS
[]´s
Alexandre Santos (AlxSts)
alxsts
Colaborador

Colaborador
 
Mensagens: 2945
Data de registro: 12 Ago 2008 15:50
Cidade/Estado: São Paulo-SP-Brasil
Curtiu: 21 vezes
Mens.Curtidas: 248 vezes

Sugestão de solução

Mensagempor JoséQuintas » 03 Jul 2021 11:36

alxsts escreveu:Não entendi bulhufas do enunciado do problema...


Para uma das colunas do tbrowse, utilizo a função acima.
Só que uso em mais de um lugar.

A idéia é substituir a coluna por algo vindo pronto do MySQL, mas sem ter que ficar repetindo tudo em cada SELECT.
Por isso a idéia de um campo calculado ou de uma stored ou de um view.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"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 de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18129
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1215 vezes

Sugestão de solução

Mensagempor JoséQuintas » 03 Jul 2021 17:17

Olhei direito, pra ver aonde usava a função PedidoStatus(), e só no tbrowse usa 3 vezes.

      oTBrowse := { ;
         { " ", { | cStatus | cStatus := PedidoStatus( :Number( "IDPEDIDO" ), ;
            :String( "PDSTATUS", 1 ), :String( "PDCONF", 1 ) ), ;
            iif( "NF." $ cStatus .OR. ( "COMPRA" $ :String( "TRANSACAO", 12 ) .AND. :String( "PDCONF", 1 ) == "S" ), " ", ;
            iif( "FATURAR" $ cStatus, Chr(2), Chr(2) ) ) }, ;
            { | cStatus | cStatus := PedidoStatus( :Number( "IDPEDIDO" ), ;
               :String( "PDSTATUS", 1 ), :String( "PDCONF", 1 ) ), ;
               iif( "NF." $ cStatus, { 9, 1 }, ;
               iif( "FATURAR" $ cStatus, { 8, 1 }, { 7, 1 } ) ) } }, ;
         { "PEDIDO",    { || Str( :Number( "IDPEDIDO" ), 6 ) } }, ;
         { "D.PEDIDO",  { || :Date( "PDDATEMI" ) } }, ;
         { "CLIENTE",   { || StrZero( :Number( "ZEROCADASTRO" ), 6 ) + " " + :String( "NOME", 30 ) } }, ;
         { "NF",        { || Str( :Number( "FILIAL" ), 2 ) + "." + Str( :Number( "ZERONOTFIS" ), 9 ) } }, ;
         { "SITUAÇÃO",  { || Pad( PedidoStatus( :Number( "IDPEDIDO" ), :String( "PDSTATUS", 1 ), :String( "PDCONF", 1 ) ), 10 ) } }, ;
         { "TRANSAÇÃO", { || :String( "TRANSACAO", 12 ) } }, ;
         { "VAL.NF",    { || Transform( :Number( "PDVALNOT" ), "999,999,999.99" ) } } }


Alterando o SELECT, elimina as chamadas à função, pelo menos no tbrowse.

      :cSQL := "SELECT IDPEDIDO, PDDATEMI, LPAD( PDCADASTRO, 6, '0' ) AS ZEROCADASTRO, " + ;
         " LEFT( JPCADASTRO.CDNOME, 30 ) AS NOME, LEFT( JPTRANSACAO.TRNOME, 12 ) AS TRANSACAO, " + ;
         " PDVALNOT, PDCONF, PDSTATUS, LPAD( JPNOTFIS.NFNOTFIS, 9, '0' ) AS ZERONOTFIS, Right( JPNOTFIS.NFFILIAL, 2 ) AS FILIAL, " + ;
         " CASE" + ;
            " WHEN PDSTATUS='C' THEN 'CANCELADO'" + ;
            " WHEN JPNOTFIS.NFPEDIDO IS NOT NULL THEN 'NF.EMITIDA'" + ;
            " WHEN NOT PDCONF = 'S' THEN 'N/CONFIRMADO'" + ;
            " ELSE 'FATURAR'" + ;
         " END AS STATUS" + ;
         " FROM JPPEDIDO " + ;
         " LEFT JOIN JPCADASTRO ON JPCADASTRO.IDCADASTRO = JPPEDIDO.PDCADASTRO" + ;
         " LEFT JOIN JPNOTFIS ON JPNOTFIS.NFPEDIDO = JPPEDIDO.IDPEDIDO " + ;
         " LEFT JOIN JPTRANSACAO ON JPTRANSACAO.IDTRANSACAO = JPPEDIDO.PDTRANSACAO " + ;
         " WHERE 1=1 " + cFiltro + ;
         " ORDER BY IDPEDIDO DESC LIMIT 2000"


Tava olhando como substituir, mas não tinha olhado sobre todos os lugares aonde usava.
Fica restando apenas um local a mais.

Tô pensando seriamente em mudar todos esses SELECTs para os tbrowses, pra STORED PROCEDURE.
Esssas 15 linhas de fonte seriam transformadas em uma única linha.
Já montei meu esquema de backup de STORED procedure/function, pelo Harbour, então tá tudo pronto.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"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 de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18129
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1215 vezes

Sugestão de solução

Mensagempor JoséQuintas » 03 Jul 2021 17:33

Tbrowse anterior:
      oTBrowse := { ;
         { " ", { | cStatus | cStatus := PedidoStatus( :Number( "IDPEDIDO" ), ;
            :String( "PDSTATUS", 1 ), :String( "PDCONF", 1 ) ), ;
            iif( "NF." $ cStatus .OR. ( "COMPRA" $ :String( "TRANSACAO", 12 ) .AND. :String( "PDCONF", 1 ) == "S" ), " ", ;
            iif( "FATURAR" $ cStatus, Chr(2), Chr(2) ) ) }, ;
         { | cStatus | cStatus := PedidoStatus( :Number( "IDPEDIDO" ), ;
               :String( "PDSTATUS", 1 ), :String( "PDCONF", 1 ) ), ;
               iif( "NF." $ cStatus, { 9, 1 }, ;
               iif( "FATURAR" $ cStatus, { 8, 1 }, { 7, 1 } ) ) } }, ;
         { "PEDIDO",    { || Str( :Number( "IDPEDIDO" ), 6 ) } }, ;
         { "D.PEDIDO",  { || :Date( "PDDATEMI" ) } }, ;
         { "CLIENTE",   { || StrZero( :Number( "ZEROCADASTRO" ), 6 ) + " " + :String( "NOME", 30 ) } }, ;
         { "NF",        { || Str( :Number( "FILIAL" ), 2 ) + "." + Str( :Number( "ZERONOTFIS" ), 9 ) } }, ;
         { "SITUAÇÃO",  { || Pad( PedidoStatus( :Number( "IDPEDIDO" ), :String( "PDSTATUS", 1 ), :String( "PDCONF", 1 ) ), 10 ) } }, ;
         { "TRANSAÇÃO", { || :String( "TRANSACAO", 12 ) } }, ;
         { "VAL.NF",    { || Transform( :Number( "PDVALNOT" ), "999,999,999.99" ) } } }
      BrowseADO( cnSQL, oTBrowse, "NOME,ZERONOTFIS,ZEROCADASTRO", { || Str( :Number( "IDPEDIDO" ), 6 ) } )
      :CloseRecordset()


TBrowse após alteração

      oTBrowse := { ;
         { " ", iif( "NF." $ :String( "STATUS" ) .OR. ( "COMPRA" $ :String( "TRANSACAO" ) .AND. :String( "PDCONF", 1 ) == "S" ), " ", ;
            iif( "FATURAR" $ :String( "STATUS" ), Chr(2), Chr(2) ) ), ;
         { || iif( "NF." $ :String( "STATUS" ), { 9, 1 }, ;
               iif( "FATURAR" $ :String( "STATUS" ), { 8, 1 }, { 7, 1 } ) ) } }, ;
         { "PEDIDO",    { || Str( :Number( "IDPEDIDO" ), 6 ) } }, ;
         { "D.PEDIDO",  { || :Date( "PDDATEMI" ) } }, ;
         { "CLIENTE",   { || StrZero( :Number( "ZEROCADASTRO" ), 6 ) + " " + :String( "NOME", 30 ) } }, ;
         { "NF",        { || Str( :Number( "FILIAL" ), 2 ) + "." + Str( :Number( "ZERONOTFIS" ), 9 ) } }, ;
         { "SITUAÇÃO",  { || :String( "STATUS", 10 ) } }, ;
         { "TRANSAÇÃO", { || :String( "TRANSACAO", 12 ) } }, ;
         { "VAL.NF",    { || Transform( :Number( "PDVALNOT" ), "999,999,999.99" ) } } }
      BrowseADO( cnSQL, oTBrowse, "NOME,ZERONOTFIS,ZEROCADASTRO", { || Str( :Number( "IDPEDIDO" ), 6 ) } )


Sei lá...
Como já estava um pouco otimizado, parece que em fonte não aliviou muito.
Em parte estava otimizado com uma prévia:
{ | cStatus | cStatus := ..., ... }

Com isso, eu usava uma variável temporária pra não ter que ficar repetindo.
Mas eliminou PedidoStatus( nIdPedido, pdStatus, pdconf ).
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"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 de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18129
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1215 vezes




Retornar para SQL

Quem está online

Usuários vendo este fórum: Nenhum usuário registrado online e 3 visitantes


Ola Amigo, espero que meu site e forum tem lhe beneficiado, com exemplos e dicas de programacao.
Entao divulgue o link da Doacao abaixo para seus amigos e redes sociais ou faça uma doacao para o site forum...
MUITO OBRIGADO PELA SUA DOACAO!
Faça uma doação para o forum
cron
v
Olá visitante, seja bem-vindo ao Fórum Clipper On Line!
Efetue o seu login ou faça o seu Registro