Jump to content
Fórum Script Brasil
  • 0

Três Funções PostgreSQL para uso diversos (Gerar Número Extenso, Cálculo CGC/CPF e Seqüêncial)


Question

 

 

===============================================================================
POSTGRESQL : Função que retorna "POR EXTENSO" um valor informado
===============================================================================

--DROP FUNCTION fnc_txt_extenso(CHAR(1),NUMERIC(32,2));
CREATE OR REPLACE FUNCTION fnc_txt_extenso(chrTipo CHAR(1), numValor NUMERIC(32,2))
RETURNS TEXT
LANGUAGE "plpgsql"
IMMUTABLE
AS
$BODY$  
DECLARE
  -- O parâmetro "tipo" é: (E) número por extenso, (M)valor monetário, (O) posição ordinários e (R) algarismo romanos...
  txtExtenso       TEXT DEFAULT '';
  numFixValor      NUMERIC(30,0);
  vchFixValor      VARCHAR(50);
  chrMilValor      CHAR(3);
  vchMilValor      VARCHAR(20);
  vchCenValor      VARCHAR(20);
  vchDezValor      VARCHAR(20);
  vchUndValor      VARCHAR(20);
  intCenValor      INTEGER;
  intDezValor      INTEGER;
  intUndValor      INTEGER;
  intQtdPartes     INTEGER;
  intQtdFracao    INTEGER;
BEGIN  

  intQtdFracao := POSITION(UPPER(chrTipo) IN 'OREM');

  IF (intQtdFracao = 0) THEN
    BEGIN
      RAISE NOTICE 'As opções para valores em extenso são "(E)xtenso, (M)onetário, (O)rdinários e (R)omanos", e não "%"', UPPER(chrTipo);
    END;
    RETURN 'ERROR';
  END IF;    

  -- Divisão entre Inteiros e decimais (??? * (10^27))...
  FOR intQtdPartes IN 1..(SELECT CASE WHEN (UPPER(chrTipo) IN ('O','R')) THEN 1 ELSE 2 END AS partes)
  LOOP

    IF (intQtdPartes = 1) THEN
      -- Pegando a parte inteira do parâmetro...
      numFixValor := TRUNC(ABS(numValor), 0);
      vchFixValor := CAST(numFixValor AS VARCHAR);
      -- Verificando se o número de digitos é na ordem de centenas.
      intQtdFracao := CASE WHEN (MOD(LENGTH(vchFixValor), 3) > 0) THEN (3 - MOD(LENGTH(vchFixValor), 3)) ELSE 0 END;
      -- Se o valor não estiver no formatado de centena....
      vchFixValor := LPAD(vchFixValor, LENGTH(vchFixValor) + intQtdFracao , '0');

    ELSE
 
     -- Pegando o valor de dois dígitos de casas decimais....
      numFixValor := (TRUNC(ABS(numValor), 2)-(TRUNC(ABS(numValor), 0)))*100;
      vchFixValor := LPAD(CAST(numFixValor AS VARCHAR), 3, '0');
      intQtdFracao := 0;

    END IF;

    -- Pegando a quantidade de milhares de centenas....
    FOR intQtdFracao IN REVERSE (TRUNC(LENGTH(vchFixValor)/3)-1) ..0
    LOOP
      chrMilValor := SUBSTRING(vchFixValor, (1 + LENGTH(vchFixValor) - (3 * (intQtdFracao + 1))), 3);
      intCenValor := CAST(SUBSTRING(chrMilValor,1, 1) AS INT);
      intDezValor := CAST(SUBSTRING(chrMilValor,2, 1) AS INT);
      intUndValor := CAST(SUBSTRING(chrMilValor,3, 1) AS INT);

      IF (chrTipo IS NULL) THEN
        vchMilValor := 'L';
        vchCenValor := 'N';
        vchDezValor := 'U';
        vchUndValor := 'L';

      ELSIF (UPPER(chrTipo) = 'O') THEN

        vchMilValor := CASE intQtdFracao WHEN 1 THEN 'milésimo '
                                         WHEN 2 THEN 'milhionésimo '
                                         WHEN 3 THEN 'bilhionésimo '
                                         WHEN 4 THEN 'trilhonésimo '
                                         WHEN 5 THEN 'quadrilhonésimo '
                                         WHEN 6 THEN 'quintilionésimo '
                                         WHEN 7 THEN 'sextilionésimo '
                                         WHEN 8 THEN 'septilionésimo '
                                         WHEN 9 THEN 'octilionésimo '
                                         ELSE '' END;

        vchCenValor := CASE intCenValor  WHEN 1 THEN 'centésimo '
                                         WHEN 2 THEN 'ducentésimo '
                                         WHEN 3 THEN 'trecentésimo '
                                         WHEN 4 THEN 'quadringentésimo '
                                         WHEN 5 THEN 'qüingentésimo '
                                         WHEN 6 THEN 'sexcentésimo '
                                         WHEN 7 THEN 'septingentésimo '
                                         WHEN 8 THEN 'octingentésimo '
                                         WHEN 9 THEN 'noningentésimo '
                                         ELSE '' END;

        vchDezValor := CASE intDezValor  WHEN 1 THEN 'décimo '
                                         WHEN 2 THEN 'vigésimo '
                                         WHEN 3 THEN 'trigêsimo '
                                         WHEN 4 THEN 'quadragésimo '
                                         WHEN 5 THEN 'qüinquagésimo '
                                         WHEN 6 THEN 'sexagésimo '
                                         WHEN 7 THEN 'septuagésimo '
                                         WHEN 8 THEN 'octoagésimo '
                                         WHEN 9 THEN 'nonagésimo '
                                         ELSE '' END;

        vchUndValor := CASE intUndValor  WHEN 1 THEN 'primeiro '
                                         WHEN 2 THEN 'segundo '
                                         WHEN 3 THEN 'terceiro '
                                         WHEN 4 THEN 'quarto '
                                         WHEN 5 THEN 'quinto '
                                         WHEN 6 THEN 'sexto '
                                         WHEN 7 THEN 'sétimo '
                                         WHEN 8 THEN 'oitavo '
                                         WHEN 9 THEN 'nono '
                                         ELSE '' END;

      ELSIF (UPPER(chrTipo) = 'R') THEN

        vchMilValor := REPEAT('|', intQtdFracao);

        vchCenValor := CASE intCenValor  WHEN 1 THEN 'C'
                                         WHEN 2 THEN 'CC'
                                         WHEN 3 THEN 'CCC'
                                         WHEN 4 THEN 'CD'
                                         WHEN 5 THEN 'D'
                                         WHEN 6 THEN 'DC'
                                         WHEN 7 THEN 'DCC'
                                         WHEN 8 THEN 'DCCC'
                                         WHEN 9 THEN 'CM'
                                         ELSE '' END;

        vchDezValor := CASE intDezValor  WHEN 1 THEN 'X'
                                         WHEN 2 THEN 'XX'
                                         WHEN 3 THEN 'XXX'
                                         WHEN 4 THEN 'XL'
                                         WHEN 5 THEN 'L'
                                         WHEN 6 THEN 'LX'
                                         WHEN 7 THEN 'LXX'
                                         WHEN 8 THEN 'LXXX'
                                         WHEN 9 THEN 'XC'
                                         ELSE '' END;

        vchUndValor:= CASE intUndValor  WHEN 1 THEN 'I'
                                        WHEN 2 THEN 'II'
                                        WHEN 3 THEN 'III'
                                        WHEN 4 THEN 'IV'
                                        WHEN 5 THEN 'V'
                                        WHEN 6 THEN 'VI'
                                        WHEN 7 THEN 'VII'
                                        WHEN 8 THEN 'VIII'
                                        WHEN 9 THEN 'IX'
                                        ELSE '' END;
 
        -- Tratamento das excepções para algarismo de ...lhões...
        IF (intQtdFracao > 0) AND (intCenValor = 0) AND (intDezValor = 0) AND (intUndValor BETWEEN 1 AND 3) THEN
          vchUndValor := REPLACE(vchUndValor, 'I', 'M');
          vchMilValor := SUBSTRING(vchMilValor, 2);
        END IF;
        
      ELSE

        vchMilValor := CASE intQtdFracao WHEN 1 THEN 'mil '
                                         WHEN 2 THEN 'milhão '
                                         WHEN 3 THEN 'bilhão '
                                         WHEN 4 THEN 'trilhão '
                                         WHEN 5 THEN 'quadrilhão '
                                         WHEN 6 THEN 'quintilhão '
                                         WHEN 7 THEN 'sextilhão '
                                         WHEN 8 THEN 'septilhão '
                                         WHEN 9 THEN 'octilião '
                                         ELSE '' END;

         vchCenValor := CASE intCenValor WHEN 1 THEN 'cem '  
                                         WHEN 2 THEN 'duzentos '
                                         WHEN 3 THEN 'trezentos '
                                         WHEN 4 THEN 'quatrocentos '
                                         WHEN 5 THEN 'quinhentos '
                                         WHEN 6 THEN 'seiscentos '
                                         WHEN 7 THEN 'setecentos '
                                         WHEN 8 THEN 'oitocentos '
                                         WHEN 9 THEN 'novecentos '
                                         ELSE '' END;

        vchDezValor := CASE intDezValor  WHEN 1 THEN (
                       CASE intUndValor  WHEN 0 THEN 'dez '
                                         WHEN 1 THEN 'onze '
                                         WHEN 2 THEN 'doze '
                                         WHEN 3 THEN 'treze '
                                         WHEN 4 THEN 'quartoze '
                                         WHEN 5 THEN 'quinze '
                                         WHEN 6 THEN 'dezesseis '
                                         WHEN 7 THEN 'dezesete '
                                         WHEN 8 THEN 'dezoito '
                                         WHEN 9 THEN 'dezenove '
                                         ELSE '' END) -- fine dell'eccezione.
                                         WHEN 2 THEN 'vinte '
                                         WHEN 3 THEN 'trinta '
                                         WHEN 4 THEN 'quarenta '
                                         WHEN 5 THEN 'cinqüenta '
                                         WHEN 6 THEN 'sessenta '
                                         WHEN 7 THEN 'setenta '
                                         WHEN 8 THEN 'oitenta '
                                         WHEN 9 THEN 'noventa '
                                         ELSE '' END;

        vchUndValor := CASE intUndValor  WHEN 1 THEN 'um '
                                         WHEN 2 THEN 'dois '
                                         WHEN 3 THEN 'três '
                                         WHEN 4 THEN 'quatro '
                                         WHEN 5 THEN 'cinco '
                                         WHEN 6 THEN 'seis '
                                         WHEN 7 THEN 'sete '
                                         WHEN 8 THEN 'oito '
                                         WHEN 9 THEN 'nove '      
                                         ELSE '' END;

        -- Tratamento das excepções para valores de dez...
        IF (intDezValor = 1) THEN
          vchUndValor := '';
        END IF;
        -- Tratamento das excepções para valores de cen...
        IF (intCenValor = 1) AND ((intDezValor > 0) OR (intUndValor > 0)) THEN
         vchCenValor := 'cento ';
        END IF;
        -- Tratamento das excepções para valores de ...lhões...
        IF (intQtdFracao > 0) AND ((intCenValor > 0) OR (intDezValor > 0) OR (intUndValor > 1)) THEN
          vchMilValor := REPLACE(vchMilValor, 'ão', 'ões');
        END IF;
        -- Tratamento da excepção referente a milhar interligada...
        IF (intQtdFracao > 0) AND ((intCenValor > 0) OR (intDezValor > 0) OR (intUndValor > 0)) AND
           (CAST(SUBSTRING(vchFixValor, (1 + LENGTH(vchFixValor) - (3 * intQtdFracao))) AS FLOAT) > 0)  THEN
          vchMilValor := vchMilValor || ' e ' ;
        END IF;
        -- Tratamento da excepção referente a centena interligada...
        IF (intCenValor > 0) AND ((intDezValor > 0) OR (intUndValor > 0)) THEN
          vchCenValor := vchCenValor || ' e ' ;
        END IF;
        -- Tratamento da excepção referente a dezena interligada...
        IF (intDezValor > 1) AND (intUndValor > 0) THEN
          vchDezValor := vchDezValor || ' e ' ;
        END IF;
       
      END IF;
      -- Tratamento das excepções referente a unidade de milhão...
      IF (UPPER(chrTipo) <> 'R') AND (intQtdFracao = 1) AND (intCenValor = 0) AND (intDezValor = 0) AND (intUndValor = 1) THEN
        vchUndValor := '';
      END IF;
      -- Tratamento das excepções referente a unidade de milhão...
      IF (UPPER(chrTipo) = 'O') AND (intQtdFracao > 1) AND (intCenValor = 0) AND (intDezValor = 0) AND (intUndValor = 1) THEN
        vchUndValor := '';
      END IF;
      -- Tratamento das excepções referente a casa de milhares...
      IF (intQtdFracao > 0) AND (intCenValor = 0) AND (intDezValor = 0) AND (intUndValor = 0) THEN
        vchMilValor := '';
      END IF;
      -- Se a parte decimais do valor for informado...
      IF (intQtdPartes = 2) AND (numFixValor > 0) THEN

        IF ((UPPER(chrTipo) = 'E') OR (UPPER(chrTipo) = 'M')) AND (txtExtenso > '') THEN
          txtExtenso := TRIM(txtExtenso) ||  ', e ';
        ELSIF (UPPER(chrTipo) = 'E') AND (txtExtenso = '') THEN
          txtExtenso := TRIM(txtExtenso) ||  'zero, ';    
        ELSIF (txtExtenso > '') THEN
          txtExtenso := TRIM(txtExtenso) ||  ', ';    
        END IF;

      END IF;  
      
      -- Concatena todas as expressões milhares, centenas, dezenas e unidades...
      txtExtenso := txtExtenso || vchCenValor || vchDezValor || vchUndValor || vchMilValor;

    END LOOP;  
    -- Se o valor informado for do tipo extenso...
    IF (UPPER(chrTipo) = 'E') AND (intQtdPartes = 2) THEN
       IF (intDezValor = 0) AND (intUndValor = 1) THEN
         txtExtenso := txtExtenso || 'décimo';
       ELSIF (numFixValor > 1) THEN
         txtExtenso := txtExtenso || 'décimos';
       END IF;
    END IF;     
    -- Se o valor informado for do tipo moeda...
    IF (UPPER(chrTipo) = 'M') AND (numFixValor > 0) THEN
      -- Se for na casa de "...lhões"
      IF (intQtdPartes = 1) AND (SUBSTRING(TRIM(txtExtenso) FROM '...$') IN ('ões', 'hão', 'ião')) THEN
        txtExtenso := txtExtenso || 'de ';
      END IF;
      -- Informar no valor a moeda corrente...
      IF (intQtdPartes = 1) AND (intCenValor = 0) AND (intDezValor = 0) AND (intUndValor = 1) THEN
         txtExtenso := txtExtenso || 'real';
      ELSIF (intQtdPartes = 1) THEN
         txtExtenso := txtExtenso || 'reais';
      ELSIF (intQtdPartes = 2) AND (intDezValor = 0) AND (intUndValor = 1) THEN
        txtExtenso := txtExtenso || 'centavo';   
      ELSIF  (intQtdPartes = 2) THEN
        txtExtenso := txtExtenso || 'centavos';   
      END IF;
     
    END IF;
    
  END LOOP;  

  /* ===================( Exemple Function Return Extensive )====================
    SELECT (seq * sup) AS "Números Arábicos" -- valores 1..100 intervalo de 1
        ,  fnc_txt_extenso('O', seq * sup) AS "Valor Ordinário"
        ,  fnc_txt_extenso('R', seq * sup) AS "Números Romanos"
        ,  fnc_txt_extenso('E', seq * sup) AS "Numeros Extenso"
        ,  fnc_txt_extenso('M', seq * sup) AS "Valor Monetário"
     FROM (SELECT generate_series(1,100,1) AS seq, 1.14 AS sup) sequencial;
    SELECT fnc_txt_extenso('E',1234567890123456789012.34) AS "Value Extensive";
    SELECT TO_CHAR(3999,'FMRN'); -- {Developer by Jair Bridi Gozze}
  ============================================================================ */
  RETURN TRIM(REPLACE(txtExtenso,'  ',' '));

END;
$BODY$;

---------------------------------------------------------------------------------
Exemplo:
---------------------------------------------------------------------------------
--OBS Veja a indicação do parâmetro que pode ser ROEM na declaração

     SELECT (seq * sup) AS "Números Arábicos" -- Apresentação de 1...100 intervalo de 1;
          ,  fnc_txt_extenso('R', seq * sup) AS "Números Romanos"
          ,  fnc_txt_extenso('O', seq * sup) AS "Extenso Ordinal"
          ,  fnc_txt_extenso('E', seq * sup) AS "Numeros Extenso"
          ,  fnc_txt_extenso('M', seq * sup) AS "Valor Monetário"
       FROM (SELECT generate_series(1,100,1) AS seq, 1.14 AS sup) sequencial;

---------------------------------------------------------------------------------
SELECT TO_CHAR(3999,'FMRN'); -- Número máximo "3999'
-- FM  Suprime espaços em branco
-- RN  Converte para o tipo "ROMANOS"

===============================================================================
POSTGRESQL : Calculo do CNP-FJ (Física/Jurídica) CPF OU CGC
===============================================================================
--DROP FUNCTION fnc_str_check_cnp_fj(INTEGER, VARCHAR(20));
CREATE OR REPLACE FUNCTION fnc_str_check_cnp_fj(intTipo INTEGER, numCNP_FJ VARCHAR(20))
RETURNS VARCHAR(25)
LANGUAGE "plpgsql"
IMMUTABLE
AS
$BODY$
DECLARE
  vchRetorno  VARCHAR(25) := 'F|I|Incorreto';
  txtNumero   VARCHAR(20) := '';
  i           INTEGER := 0;    
  intNumDig_1 INTEGER;
  intNumDig_2 INTEGER;
  intCalDig_1 INTEGER;
  intCalDig_2 INTEGER;
BEGIN

  -- Limpando a informação...
  FOR i IN 1..LENGTH(COALESCE(numCNP_FJ, '')) LOOP
    IF (POSITION(SUBSTRING(numCNP_FJ, i, 1) IN '0123456789') > 0) THEN
     txtNumero := txtNumero || SUBSTRING(numCNP_FJ, i, 1);
    END IF;
  END LOOP;
 
  -- SE A INFORMAÇÃO FOR DE UM CADASTRO NACIONAL DE PESSOA JURÍDICA...
  IF (CAST(char_length(txtNumero) AS INTEGER) = 14) THEN

    intCalDig_1 := 0;
    intCalDig_2 := 0;
    -- Coleta do primeiro dígito verificador CGC
    intNumDig_1 := CAST(SUBSTRING(txtNumero, 13, 1) AS INTEGER);
    intNumDig_2 := CAST(SUBSTRING(txtNumero, 14, 1) AS INTEGER);
    txtNumero   := SUBSTRING(txtNumero, 1, 12);

    -- Calculo do CNP-Jurídica...
    FOR i IN 1..12 LOOP
      intCalDig_1 := intCalDig_1 + (CAST(SUBSTRING(txtNumero, i, 1) AS INTEGER) * CAST(SUBSTRING('543298765432', i, 1) AS INTEGER));
    END LOOP;

    intCalDig_1 := MOD(intCalDig_1,11);

    IF (intCalDig_1 = 0) OR (intCalDig_1 = 1) THEN
      intCalDig_1 := 0;
    ELSE
      intCalDig_1 := 11 - intCalDig_1;
    END IF;
    -- Coleta do segundo dígito verificador do CGC
    txtNumero := txtNumero || CAST(intCalDig_1 AS CHAR(1));

    FOR i IN 1..13 LOOP
      intCalDig_2 := intCalDig_2 + (CAST(SUBSTRING(txtNumero, i, 1) AS INTEGER) * CAST(SUBSTRING('6543298765432', i, 1) AS INTEGER));
    END LOOP;

    intCalDig_2 := MOD(intCalDig_2,11);

    IF (intCalDig_2 = 0) OR (intCalDig_2 = 1) THEN
      intCalDig_2 := 0;
    ELSE
      intCalDig_2 := 11 - intCalDig_2;
    END IF;
    -- Retorno do calculo do CNP-Jurídica..
    IF (intCalDig_1 = intNumDig_1) AND (intCalDig_2 = intNumDig_2) THEN
      vchRetorno = 'V|J|' || SUBSTRING(txtNumero,1,2) || '.' || SUBSTRING(txtNumero,3,3) || '.' || SUBSTRING(txtNumero,6,3) || '/' || SUBSTRING(txtNumero,9,4) || '-' || CAST(intCalDig_1 AS CHAR(1)) || CAST(intCalDig_2 AS CHAR(1));
    ELSE
      vchRetorno = 'F|J|CNP-J Dígito:' || CAST(intCalDig_1 AS CHAR(1)) || CAST(intCalDig_2 AS CHAR(1));
    END IF;
    -- Retorna o Resultado...  
    IF (SUBSTRING(vchRetorno, 1, 1) = 'V') AND (SUBSTRING(txtNumero, 1, 11) = SUBSTRING(txtNumero, 3, 11)) THEN
      RAISE NOTICE 'Cadastro de pessoa incorreto!';
      vchRetorno = 'V|I|CNP-J Invalido';
    END IF;

  -- SE A INFORMAÇÃO FOR DE UM CADASTRO NACIONAL DE PESSOA FÍSICA...
  ELSIF (CAST(char_length(txtNumero) AS INTEGER) = 11) THEN

    intCalDig_1 := 0;
    intCalDig_2 := 0;
    -- Coleta do primeiro dígito verificador CPF..
    intNumDig_1 := CAST(SUBSTRING(txtNumero, 10, 1) AS INTEGER);
    intNumDig_2 := CAST(SUBSTRING(txtNumero, 11, 1) AS INTEGER);
    txtNumero   := SUBSTRING(txtNumero, 1, 9);

    -- Calculo do CNP-Física...
    FOR i IN 1..9 LOOP
      intCalDig_1 := intCalDig_1 + (CAST(SUBSTRING(txtNumero, i, 1) AS INTEGER) * (11 - i));
    END LOOP;

    intCalDig_1 := MOD(intCalDig_1,11);

    IF (intCalDig_1 = 0) OR (intCalDig_1 = 1) THEN
      intCalDig_1 := 0;
    ELSE
      intCalDig_1 := 11 - intCalDig_1;
    END IF;

    -- Coleta do segundo dígito verificador CPF..
    txtNumero := txtNumero || CAST(intCalDig_1 AS CHAR(1));

    FOR i IN 1..10 LOOP
      intCalDig_2 := intCalDig_2 + (CAST(SUBSTRING(txtNumero, i, 1) AS INTEGER) * (12 - i));
    END LOOP;

    intCalDig_2 := MOD(intCalDig_2,11);

    IF (intCalDig_2 = 0) OR (intCalDig_2 = 1) THEN
      intCalDig_2 := 0;
    ELSE
      intCalDig_2 := 11 - intCalDig_2;
    END IF;

    -- Retorno do calculo do CNP-Física...
    IF (intCalDig_1 = intNumDig_1) AND (intCalDig_2 = intNumDig_2) THEN
       vchRetorno = 'V|F|' || SUBSTRING(txtNumero,1,3) || '.' || SUBSTRING(txtNumero,4,3) || '.' || SUBSTRING(txtNumero,7,3) ||  '-' || CAST(intCalDig_1 AS CHAR(1)) || CAST(intCalDig_2 AS CHAR(1));
    ELSE
       vchRetorno = 'F|F|CNP-F Dígito:' || CAST(intCalDig_1 AS CHAR(1)) || CAST(intCalDig_2 AS CHAR(1));
    END IF;
 
    -- Retorna o resultado...
    IF (SUBSTRING(vchRetorno, 1, 1) = 'V') AND (SUBSTRING(txtNumero, 1, 8 ) = SUBSTRING(txtNumero, 3, 8)) THEN
      RAISE NOTICE 'Cadastro de pessoa incorreto!';
      vchRetorno = 'V|I|CNP-F Invalido';
    END IF;
      
  END IF;
  -- Retorno do calculo do Cadastro Nacional de Pessoa...
  RETURN CASE intTipo WHEN 0 THEN SUBSTRING(vchRetorno, 1, 1)
                      WHEN 1 THEN SUBSTRING(vchRetorno, 3, 1)
                      WHEN 2 THEN SUBSTRING(vchRetorno, 5, 20)
                      WHEN 3 THEN REPLACE(SUBSTRING(vchRetorno, 1, 3), '|', '')
                      ELSE vchRetorno END;
  -- Retorno do resultado...
  -- ===================( Exemple Function Return Extensive )====================
  --  SELECT fnc_str_check_cnp_fj(2, "12345678901") AS "Value False Digite";
  --  {Developer by Jair Bridi Gozze}
  -- ============================================================================
END;
$BODY$;

--DROP FUNCTION fnc_sequencia(TEXT, INT);
CREATE OR REPLACE FUNCTION fnc_sequencia(Consulta IN TEXT, intSEQ IN INT)
RETURNS SETOF RECORD
LANGUAGE "plpgsql"
VOLATILE AS
$BODY$
DECLARE
  intSQL INTEGER DEFAULT intSEQ;
  txtSQL TEXT DEFAULT '';
  recSQL RECORD;
BEGIN
  txtSQL = 'SELECT 0 AS seq, STRING_TO_ARRAY(TRANSLATE((CAST(x AS TEXT)),"(§)",""),",") AS x FROM (SELECT x FROM (';
  txtSQL =  TRANSLATE(txtSQL, '"§','''"') || TRIM(REPLACE(Consulta, '"', '''')) || ') x) w';
  -- Executando a pesquisa da consulta inicial...
  BEGIN
    FOR recSQL IN EXECUTE txtSQL
    LOOP
      recSQL.seq = intSQL;
      intSQL = intSQL + 1;
      RETURN NEXT recSQL;
    END LOOP;

  EXCEPTION
    WHEN RAISE_EXCEPTION THEN
      RAISE WARNING 'Erro na seqüência " % ", verifique...', intSQL;  
    WHEN OTHERS THEN
      RAISE NOTICE 'Erro na consulta ".. % ..", verifique na seqüência "%" informada!', Consulta, intSQL;
  END;  
  RETURN;
  -- ====================( Exemple Function Return Sequence )====================
  --  SELECT myFields[1] AS Field_1, myFields[2] AS Field_2, myFields[3] AS Field_3
  -- , mySeq AS Sequence FROM fnc_sequencia('SELECT * FROM my_Table WHERE (Fields_1
  -- = "XYZ") ORDER BY Fields_1', 10) my_Query (mySeq INT, myFields TEXT[]);
  -- {Developer by Jair Bridi Gozze}
  -- ============================================================================
END;
$BODY$;

Link to post
Share on other sites

0 answers to this question

Recommended Posts

There have been no answers to this question yet

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



  • Forum Statistics

    • Total Topics
      148720
    • Total Posts
      644545
×
×
  • Create New...