Página 1 de 1

variável por referência

Enviado: 11 Jun 2025 10:17
por JoséQuintas
Comecei a usar variável por referência.
Mas só funciona com STORED PROCEDURE.
Alterei toda parte de geração de XML de NFE.

Rotina de totais:

Código: Selecionar todos

CREATE PROCEDURE ze_XmlNfeTotais( nIdNotFis INT(11), INOUT cEndXml TEXT )

BEGIN

DECLARE cThisXml TEXT CHARSET latin1;
DECLARE nIcmBas, nIcmVal, nSubBas, nSubVal, nValPro, nValFre, nValSeg DECIMAL(16,2);
DECLARE nValDes, nIIVal, nPisVal, nCofVal, nValOut, nImpVal, nValNot  DECIMAL(16,2);
DECLARE nIpiVal, nDifValf, nMonoBas, nDifVali, nMonoAliq DECIMAL(16,2);
DECLARE nComplementar INT(11);
DECLARE dData DATE;

SET cThisXml := '';
SET nMonoAliq := 1.1200;

SELECT NFICMBAS, NFICMVAL, NFSUBBAS, NFSUBVAL, NFVALPRO, NFVALFRE,
   NFVALSEG, NFVALDES, NFIIVAL, NFIPIVAL, NFPISVAL, NFCOFVAL, NFVALOUT + NFVALEXT,
   NFIMPVAL, NFVALNOT, COALESCE( SUM( IPDIFVALF ), 0.00 ), COALESCE( SUM( IPDIFVALI ), 0.00 ),
   SUM( IF( NFCFOP = '1.604' OR INSTR( IENOME, ' DE ICMS' ) != 0, 1, 0 ) ),
   SUM( IF( IENOME LIKE '%LEO DIESEL%', IPQTDE, 0 ) ), NFDATEMI
FROM JPNOTFIS
LEFT JOIN JPPEDIDO ON JPPEDIDO.IDPEDIDO = JPNOTFIS.NFPEDIDO
LEFT JOIN JPITPED ON JPITPED.IPPEDIDO = JPPEDIDO.IDPEDIDO
LEFT JOIN JPITEM ON JPITEM.IDPRODUTO = JPITPED.IPPRODUTO
WHERE IDNOTFIS = nIdNotFis
INTO nIcmBas, nIcmVal, nSubBas, nSubVal, nValPro, nValFre, nValSeg, nValDes, nIIVal, nIpiVal,
   nPisVal, nCofVal, nValOut, nImpVal, nValNot, nDifValf, nDifVali, nComplementar, nMonoBas,
   dData ;

SET cThisXml := CONCAT( cThisXml,
   '<total>',
   '<ICMSTot>',
   ze_XmlTag( 'vBC',          nIcmBas ),
   ze_XmlTag( 'vICMS',        nIcmVal ),
   ze_XmlTag( 'vICMSDeson',   '0.00' ),
   ze_XmlTag( 'vFCPUFDest',   nDifValf ),
   ze_XmlTag( 'vICMSUFDest',  nDifVali ),
   ze_XmlTag( 'vICMSUFRemet', '0.00' ),
   ze_XmlTag( 'vFCP', '0.00' ),
   ze_XmlTag( 'vBCST',        nSubBas ),
   ze_XmlTag( 'vST',          nSubVal ),
   ze_XmlTag( 'vFCPST', '0.00' ),
   ze_XmlTag( 'vFCPSTRet', '0.00' ),
   IF(  nMonoBas = 0, '',
      CONCAT( ze_XmlTag( 'qBCMonoRet', nMonoBas ),
              ze_XmlTag( 'vICMSMonoRet', ROUND( nMonoBas * nMonoAliq, 2 ) ) ) ),
   ze_XmlTag( 'vProd',        IF( nComplementar = 1, '0.00', nValPro ) ),
   ze_XmlTag( 'vFrete',       nValFre ),
   ze_XmlTag( 'vSeg',         nValSeg ),
   ze_XmlTag( 'vDesc',        nValDes ),
   ze_XmlTag( 'vII',          nIIVal ),
   ze_XmlTag( 'vIPI',         nIpiVal ),
   ze_XmlTag( 'vIPIDevol', '0.00' ),
   ze_XmlTag( 'vPIS',         nPisVal ),
   ze_XmlTag( 'vCOFINS',      nCofVal ),
   ze_XmlTag( 'vOutro',       nValOut ),
   ze_XmlTag( 'vNF',          IF( nComplementar = 1, '0.00', nValNot ) ),
   IF( nImpVal = 0, '', ze_XmlTag( 'vTotTrib',  nImpVal ) ),
   '</ICMSTot>',
   '</total>' );

SET cEndXml := CONCAT( cEndXml, cThisXml );

END
Basicamente é colocar o INOUT no parâmetro.

A parte prática do MySQL é que ele gera conforme variável, sem precisar conversão.
CONCAT() é juntar as partes.
Se definiu a variável com 2 decimais, é com duas decimais que vai juntar, simples assim.

Código: Selecionar todos

DECLARE x DECIMAL(10,2);
SET x := 2;
SET x := CONCAT( "[cIcms]", x, "[/cIcms]" )
Ou a ze_XmlTag("cIcms",x)

O resultado vai ser "[cIcms]2.00[/cIcms]"

variável por referência

Enviado: 11 Jun 2025 10:26
por JoséQuintas
E um trecho do produto

Código: Selecionar todos

   CALL ze_xmlnfeprodutoveiculo( nIdItPed, cThisXml ) ;
   CALL ze_xmlnfeprodutomedicamento( nIdItPed, cThisXml ) ;
   CALL ze_xmlnfeprodutoarmamento( nIdItPed, cThisXml ) ;
   CALL ze_xmlNfeprodutocombustivel( nIdItPed, cThisXml, cInfAdProduto ) ;

   SET cThisXml := CONCAT( cThisXml, '</prod>' );
   SET cThisXml := CONCAT( cThisXml, '<imposto>' );

   IF nImpVal <> 0 THEN
      SET cThisXml := CONCAT( cThisXml, ze_XmlTag( 'vTotTrib', nImpVal ) );
   END IF;

   CALL ze_xmlnfeprodutoicms( nIdItPed, cThisXml, cInfAdProduto );
   CALL ze_xmlnfeprodutoipi( nIdItPed, cThisXml ) ;
   CALL ze_xmlnfeprodutoii( nIdItPed, cThisXml ) ;
   CALL ze_xmlnfeprodutopis( nIdItPed, cThisXml );
   CALL ze_xmlnfeprodutocofins( nIdItPed, cThisXml );
   CALL ze_XmlNfeProdutoISS( nIdItPed, cThisXml ) ;

   SET cThisXml := CONCAT( cThisXml, '</imposto>' );

   SET cThisXml := CONCAT( cThisXml, '</det>' );

   SET cEndXml := CONCAT( cEndXml, cThisXml );
Fiz isso por causa do cInfAdProduto, pra já carregar o complemento nas rotinas que interessam.
obs. ANP na rotina de combustivel, e obs. monofásico na rotina de monofásico.
Assim não precisa sair caçando rotinas especiais, elas ficam no lugar adequado.