Clipper On Line • Ver Tópico - Rotina Harbour pra SQL

Rotina Harbour pra SQL

Discussão sobre SQL

Moderador: Moderadores

 

Rotina Harbour pra SQL

Mensagempor JoséQuintas » 29 Ago 2021 10:18

Aquele negócio do estoque, resolvi com esta função:

CREATE PROCEDURE ze_ProdutoBaixaEstoque( nIdProduto INT(11), nQtde DECIMAL(16,5), cDeposito CHAR(1) )

BEGIN

IF cDeposito = '1' THEN
   UPDATE JPITEM
   SET IEQTD1 = IEQTD1 + nQtde
   WHERE IDPRODUTO = nIdProduto;
END IF;

IF cDeposito = '2' THEN
   UPDATE JPITEM
   SET IEQTD2 = IEQTD2 + nQtde
   WHERE IDPRODUTO = nIdProduto;
END IF;

IF cDeposito = '3' THEN
   UPDATE JPITEM
   SET IEQTD3 = IEQTD3 + nQtde
   WHERE IDPRODUTO = nIdProduto;
END IF;

IF cDeposito = '4' THEN
   UPDATE JPITEM
   SET IEQTD4 = IEQTD4 + nQtde
   WHERE IDPRODUTO = nIdProduto;
END IF;

IF cDeposito = '5' THEN
   UPDATE JPITEM
   SET IEQTD5 = IEQTD5 + nQtde
   WHERE IDPRODUTO = nIdProduto;
END IF;

IF cDeposito = '6' THEN
   UPDATE JPITEM
   SET IEQTD6 = IEQTD6 + nQtde
   WHERE IDPRODUTO = nIdProduto;
END IF;

IF cDeposito = '7' THEN
   UPDATE JPITEM
   SET IEQTD7 = IEQTD7 + nQtde
   WHERE IDPRODUTO = nIdProduto;
END IF;

IF cDeposito = '8' THEN
   UPDATE JPITEM
   SET IEQTD8 = IEQTD8 + nQtde
   WHERE IDPRODUTO = nIdProduto;
END IF;

IF cDeposito = '9' THEN
   UPDATE JPITEM
   SET IEQTD9 = IEQTD9 + nQtde
   WHERE IDPRODUTO = nIdProduto;
END IF;

END


É grande mas.... tudo bem.

Agora esta rotina aqui:

STATIC FUNCTION UpdateJPESTOQUE( nIdEstoque, nSomaTira )

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

   WITH OBJECT cnSQL
      :cSQL := "UPDATE JPITEM" + ;
         " LEFT JOIN" + ;
            " ( SELECT ESPRODUTO, ESNUMDEP, ESQTDE * IF( ESTIPLAN = '1', -1, 1 ) * " + NumberSQL( nSomaTira ) + " AS SOMA" + ;
               " FROM JPESTOQUE WHERE IDESTOQUE = " + NumberSQL( nIdEstoque ) + " ) AS A" + ;
            " ON A.ESPRODUTO = JPITEM.IDPRODUTO" + ;
         " SET" + ;
            " JPITEM.IEQTD1 = IEQTD1 + IF( A.ESNUMDEP BETWEEN '2' AND '9', 0, A.SOMA )," + ;
            " JPITEM.IEQTD2 = IEQTD2 + IF( A.ESNUMDEP = '2', A.SOMA, 0 )," + ;
            " JPITEM.IEQTD3 = IEQTD3 + IF( A.ESNUMDEP = '3', A.SOMA, 0 )," + ;
            " JPITEM.IEQTD4 = IEQTD4 + IF( A.ESNUMDEP = '4', A.SOMA, 0 )," + ;
            " JPITEM.IEQTD5 = IEQTD5 + IF( A.ESNUMDEP = '5', A.SOMA, 0 )," + ;
            " JPITEM.IEQTD6 = IEQTD6 + IF( A.ESNUMDEP = '6', A.SOMA, 0 )," + ;
            " JPITEM.IEQTD7 = IEQTD7 + IF( A.ESNUMDEP = '7', A.SOMA, 0 )," + ;
            " JPITEM.IEQTD8 = IEQTD8 + IF( A.ESNUMDEP = '8', A.SOMA, 0 )," + ;
            " JPITEM.IEQTD9 = IEQTD9 + IF( A.ESNUMDEP = '9', A.SOMA, 0 )" + ;
         " WHERE JPITEM.IDPRODUTO = A.ESPRODUTO"
      :ExecuteCmd()
   ENDWITH

   RETURN NIL


Basta usar a função do SQL no lugar dela.
Ou uma stored procedure que chama a outra função, a partir do lançamento do estoque, de qualquer jeito vai ficar menor.

Nota: o que futuramente poderia ser uma "trigger", de acionamento automático.
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: 18014
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Rotina Harbour pra SQL

Mensagempor JoséQuintas » 30 Ago 2021 13:46

Encontrei o lado ruim da "coisa".
Dividir em stored procedures menores é legal na criação mas.... péssimo quando dá erro.
A mensagem de erro do MySQL se limita à primeira procedure.

Exemplo:
Dividi o cálculo de impostos, uma rotina pra cada imposto.
E a rotina principal chama as rotinas de cada imposto.
Em caso de erro, só mostra a linha da procedure principal, e tem que sair caçando em qual sub-procedure deu erro.

Acabei juntando tudo.

Apenas separei em blocos, usando BEGIN END, assim a declaração de variáveis fica limitada a cada bloco.
Vira como se fossem funções isoladas.
Apenas exemplo:

BEGIN

DECLARE nValPro INT(11) DEFAULT 1000;

BEGIN

   DECLARE nIcmAli INT(11) DEFAULT 18;
   DECLARE nIcmVal INT(11) DEFAULT 0;

   SET nIcmVal := nValPro * nIcmAli / 100;

   UPDATE JPITPED SET IPICMALI = nIcmAli, IPICMVAL = nIcmVal WHERE IDITPED = nIdItPed;

END;

BEGIN

   DECLARE nPisAli INT(11) DEFAULT 3;
   DECLARE nPisVal INT(11) DEFAULT 0;

   SET nPisVal = nValPro * nPisAli / 100;

   UPDATE JPITPED SET IPIPISALI = nPisAli, IPPISVAL = nPisVal WHERE IDITPED = nIdItPed;

END;

END


Pelo menos, apesar de tudo embolado, permite trabalhar com poucas variáveis por vez.
E desse jeito vou ter a linha do erro.

Isso altera totalmente o que eu tinha planejado no início, de procedures pequenas.

Quanto a limite: na internet cita 1GB, mas que de qualquer jeito fica limitado ao MaxAllowedPackedSize, que por default são 4MB.

Os END internos tem ponto e vírgula.
É só lembrar que, apesar de tudo, tudo isso é uma única linha... e o SQL se orienta pelo ponto e vírgula pra saber sobre como tratar a execução disso tudo.
Só depois de um END de um bloco é que vai começar o bloco seguinte, então vai um ponto e vírgula no END anterior.
E nos DECLARE, pra terminar de declarar a variável antes de prosseguir, nos comandos, nos END IF, etc.
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: 18014
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Rotina Harbour pra SQL

Mensagempor JoséQuintas » 30 Ago 2021 14:02

deletado.png


Só sobrou uma dessas todas.
NÃO SEI porque o git não mostrou todas excluídas com (X).
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: 18014
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Rotina Harbour pra SQL

Mensagempor JoséQuintas » 31 Ago 2021 06:40

CREATE FUNCTION ze_AliquotaICMS( cUF1 VARCHAR(2), cUF2 VARCHAR(2) )
RETURNS DECIMAL(10,2)

BEGIN

DECLARE nAliquota DECIMAL(10,2);

SELECT ALIQUOTA
INTO nAliquota
FROM
(
SELECT 'AC' as ORIGEM, 'AC' AS DESTINO, CAST( 12 AS DECIMAL(10,2) ) AS ALIQUOTA
UNION SELECT 'AL', 'AL', 18
UNION SELECT 'AM', 'AM', 18
UNION SELECT 'AP', 'AP', 18
UNION SELECT 'BA', 'BA', 18
UNION SELECT 'CE', 'CE', 18
UNION SELECT 'DF', 'DF', 18
UNION SELECT 'ES', 'ES', 17
UNION SELECT 'GO', 'GO', 17
UNION SELECT 'MA', 'MA', 18
UNION SELECT 'MG', 'MG', 18
UNION SELECT 'MG', 'PR', 12
UNION SELECT 'MG', 'RJ', 12
UNION SELECT 'MG', 'RS', 12
UNION SELECT 'MG', 'SC', 12
UNION SELECT 'MG', 'SP', 12
UNION SELECT 'MG', '**', 7
UNION SELECT 'MT', 'MT', 17
UNION SELECT 'MS', 'MS', 17
UNION SELECT 'PA', 'PA', 17
UNION SELECT 'PB', 'PB', 18
UNION SELECT 'PE', 'PE', 18
UNION SELECT 'PI', 'PI', 18
UNION SELECT 'PR', 'PR', 18
UNION SELECT 'RJ', 'RJ', 20
UNION SELECT 'RJ', 'MG', 12
UNION SELECT 'RJ', 'PR', 12
UNION SELECT 'RJ', 'RS', 12
UNION SELECT 'RJ', 'SC', 12
UNION SELECT 'RJ', 'SP', 12
UNION SELECT 'RJ', '**', 7
UNION SELECT 'RN', 'RN', 18
UNION SELECT 'RO', 'RO', 17.5
UNION SELECT 'RR', 'RR', 17
UNION SELECT 'RS', 'RS', 18
UNION SELECT 'RS', 'MG', 12
UNION SELECT 'RS', 'PR', 12
UNION SELECT 'RS', 'MS', 12
UNION SELECT 'RS', 'SC', 12
UNION SELECT 'RS', 'SP', 12
UNION SELECT 'RS', '**', 7
UNION SELECT 'SC', 'SC', 17
UNION SELECT 'SC', 'MG', 12
UNION SELECT 'SC', 'PR', 12
UNION SELECT 'SC', 'MS', 12
UNION SELECT 'SC', 'PB', 12
UNION SELECT 'SC', 'RS', 12
UNION SELECT 'SC', 'SP', 12
UNION SELECT 'SC', '**', 7
UNION SELECT 'SP', 'SP', 18
UNION SELECT 'SP', 'MG', 12
UNION SELECT 'SP', 'PR', 12
UNION SELECT 'SP', 'RJ', 12
UNION SELECT 'SP', 'RS', 12
UNION SELECT 'SP', 'SC', 12
UNION SELECT 'SP', '**', 7
UNION SELECT 'SE', 'SE', 18
UNION SELECT 'TO', 'TO', 18
UNION SELECT '**', '**', 12
) AS TABELA
INNER JOIN ( SELECT cUF1 AS ORIGEM, cUF2 AS DESTINO ) AS PROCURA
ON TABELA.ORIGEM IN ( PROCURA.ORIGEM, '**' ) AND TABELA.DESTINO IN ( PROCURA.DESTINO, '**' )
LIMIT 1;

RETURN nAliquota;

END


Na prática a gente não usa essa tabela simples de ICMS, mas é uma possibilidade.
Depois pra obter a aliquota:

SELECT cliet.nempresa.uf, cliente.uf, ze_AliquotaIcms( empresa.uf, cliente.uf )
from cliente
join empresa


a lista com aliquota de icms pra todos os clientes.
'
como no mysql não tem limite de tabelas, poderia existir essa tabela de aliquotas no banco de dados.
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: 18014
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Rotina Harbour pra SQL

Mensagempor JoséQuintas » 02 Set 2021 18:39

Como mudei tudo pra uma procedure só....

OPEN curItPed;

Produtos: LOOP

BEGIN

DECLARE nIdItPed INT(11) DEFAULT 0;
DECLARE nValPro, nValNot, nIIBas, nIIVal, nIIAli DECIMAL(16,2) DEFAULT 0;
DECLARE nIssBas, nIssAli, nIssVal DECIMAL(16,2) DEFAULT 0;
DECLARE nIpiBas, nIpiAli, nIpiVal DECIMAL(16,2) DEFAULT 0;
DECLARE nIcmAli, nIcmBas, nIcmRed, nIcmVal DECIMAL(16,2) DEFAULT 0;
DECLARE cIcmCst, cIpiIcm VARCHAR(10) DEFAULT '';
DECLARE nFcpAli, nFcpVal DECIMAL(16,2) DEFAULT 0;
DECLARE nSubIva, nSubRed, nSubAli, nSubBas, nSubVal DECIMAL(16,2) DEFAULT 0;
DECLARE cDifCal VARCHAR(5) DEFAULT '';
DECLARE nDifBas, nDifAlii, nDifAliu, nDifAlif, nDifVali, nDifValf DECIMAL(16,2) DEFAULT 0;
DECLARE nPisBas, nPisAli, nPisVal, nCofBas, nCofAli, nCofVal DECIMAL(16,2) DEFAULT 0;
DECLARE nImpVal, nImpAli DECIMAL(16,2) DEFAULT 0;
DECLARE cCFOP VARCHAR(5) DEFAULT '';
DECLARE nIcsBas, nIcsAli, nIcsVal DECIMAL(16,2) DEFAULT 0;
DECLARE nValFre, nValSeg, nValOut, nValExt, nValDes DECIMAL(16,2) DEFAULT 0;

   FETCH curItPed INTO nIdItPed,
      nValPro, nValNot, nIIBas, nIIVal, nIIAli,
      nIssBas, nIssAli, nIssVal,
      nIpiBas, nIpiAli, nIpiVal,
      nIcmAli, nIcmBas, nIcmRed, nIcmVal,
      cIcmCst, cIpiIcm,
      nFcpAli, nFcpVal,
      nSubIva, nSubRed, nSubAli, nSubBas, nSubVal,
      cDifCal,
      nDifBas, nDifAlii, nDifAliu, nDifAlif, nDifVali, nDifValf,
      nPisBas, nPisAli, nPisVal, nCofBas, nCofAli, nCofVal,
      nImpVal, nImpAli,
      cCfop, nIcmBas, nIcsAli, nIcsVal, nValFre, nValSeg, nValOut, nValExt, nValDes;
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: 18014
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Anterior



Retornar para SQL

Quem está online

Usuários vendo este fórum: Nenhum usuário registrado online e 7 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