Rotina Harbour pra SQL

Forum sobre SQL.

Moderador: Moderadores

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

Rotina Harbour pra SQL

Mensagem por JoséQuintas »

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

Código: Selecionar todos

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:

Código: Selecionar todos

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 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

Rotina Harbour pra SQL

Mensagem por JoséQuintas »

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:

Código: Selecionar todos

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 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

Rotina Harbour pra SQL

Mensagem por JoséQuintas »

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 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

Rotina Harbour pra SQL

Mensagem por JoséQuintas »

Código: Selecionar todos

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:

Código: Selecionar todos

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 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

Rotina Harbour pra SQL

Mensagem por JoséQuintas »

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

Código: Selecionar todos

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 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