Realmente, estamos tomando uma surra, por questões de conceitos de SQL já impregnados na gente, tanto que com ajuda de outro colega reformulamos a function conforme abaixo:

CREATE OR REPLACE FUNCTION TRAVA_INADIMPLENTES ( PDIAS_VENCIDO INTEGER, PUND_LOCAL VARCHAR(3), PCNPJ VARCHAR(18) ) RETURNS BOOLEAN AS
  $$
  DECLARE
     SPERMITE_BLOQUEIO VARCHAR(1);
     INRO_REGISTROS INTEGER;
     --
     RDAT RECORD;
  BEGIN
     IF ( PCNPJ = '' ) THEN

        FOR RDAT IN
SELECT TIPO_DOC AS FAT_DOCUMENTO, FIL_ORIG AS FAT_EMISSORA, FATURA AS FAT_NUMERO, ANO AS FAT_ANO, PARCELA AS FAT_PARCELA, CGC AS COD_CLIENTE
           FROM CTAS_RECEBER
           WHERE ( STATUS NOT IN ( 'CA', 'CO' ) ) AND ( DT_PAGTO IS NULL )
             AND ( ( CURRENT_TIMESTAMP - DT_VENCTO ) >= PDIAS_VENCIDO )
           ORDER BY DT_VENCTO, TIPO_DOC, FIL_ORIG, FATURA, ANO
        LOOP
           SELECT PERMITE_PROTESTO
           FROM CLIENTES
           WHERE CGC = RDAT.COD_CLIENTE
           INTO SPERMITE_BLOQUEIO;

           IF (SPERMITE_BLOQUEIO = 'T') THEN
              --
              UPDATE CLIENTES
SET INADIMPLENTE = 'T', OPERADOR = 'BLOQUEIO AUTOMATICO', DT_ALTERACAO = CURRENT_TIMESTAMP
              WHERE CGC = RDAT.COD_CLIENTE;
              --
              INSERT INTO HIST_COBRANCA
VALUES ( RDAT.FAT_DOCUMENTO, RDAT.FAT_EMISSORA, RDAT.FAT_NUMERO, RDAT.FAT_ANO, RDAT.FAT_PARCELA, CURRENT_TIMESTAMP, PUND_LOCAL, 'BLOQUEIO AUTOMATICO DE INADIMPLENTE', 'BLOQUEIO AUTOMATICO', CURRENT_TIMESTAMP );
           END IF;
        END LOOP;
     ELSE
        FOR RDAT IN
SELECT TIPO_DOC AS FAT_DOCUMENTO, FIL_ORIG AS FAT_EMISSORA, FATURA AS FAT_NUMERO, ANO AS FAT_ANO, PARCELA AS FAT_PARCELA, CGC AS COD_CLIENTE
           FROM CTAS_RECEBER
           WHERE ( STATUS NOT IN ( 'CA', 'CO' )) AND ( DT_PAGTO IS NULL )
             AND ( ( CURRENT_TIMESTAMP - COB.DT_VENCTO ) >= PDIAS_VENCIDO )
             AND ( CGC = PCNPJ )
           ORDER BY DT_VENCTO, TIPO_DOC, FIL_ORIG, FATURA, ANO
        LOOP
SELECT PERMITE_PROTESTO
           FROM CLIENTES
           WHERE CGC = RDAT.COD_CLIENTE
           INTO SPERMITE_BLOQUEIO;

           IF ( SPERMITE_BLOQUEIO = 'T' ) THEN
              --
              UPDATE CLIENTES
SET INADIMPLENTE = 'T', OPERADOR = 'BLOQUEIO AUTOMATICO', DT_ALTERACAO = CURRENT_TIMESTAMP
              WHERE CGC = RDAT.COD_CLIENTE;
              --
              SELECT COUNT( FAT_NUMERO )
              FROM HIST_COBRANCA
WHERE ( FAT_DOCUMENTO = RDAT.FAT_DOCUMENTO ) AND ( FAT_EMISSORA = RDAT.FAT_EMISSORA ) AND ( FAT_NUMERO = RDAT.IFAT_NUMERO ) AND ( FAT_ANO = RDTA.SFAT_ANO ) AND ( FAT_PARCELA = IFAT_PARCELA ) AND ( DTA_LANCAMENTO = CURRENT_TIMESTAMP )
              INTO INRO_REGISTROS;
              --
              IF ( INRO_REGISTROS = 0 ) THEN
                 INSERT INTO HIST_COBRANCA
VALUES ( RDAT.FAT_DOCUMENTO, RDAT.FAT_EMISSORA, RDAT.FAT_NUMERO, RDAT.FAT_ANO, RDAT.FAT_PARCELA, CURRENT_TIMESTAMP, PUND_LOCAL, 'BLOQUEIO AUTOMATICO DE INADIMPLENTE', 'BLOQUEIO AUTOMATICO', CURRENT_TIMESTAMP );
              END IF;
              --
           END IF;
        END LOOP;
     END IF;
RETURN TRUE;
  END;
  $$
  LANGUAGE 'PLPGSQL';

Fabrízio de Royes Mello escreveu:
Caro Paulo,


2009/4/17 Paulo (O2 Tecnologia) <[email protected] <mailto:[email protected]>>



    Estamos migrando nossos sistemas de Firebird para PostgreSQL, estamos
    com 99% do processo homologado, mas tropeçamos numa store
    procedure, que
    não estamos conseguindo portar, ao tentarmos inclui-la no
    PostgreSQL, é
    acusado o seguinte erro "sintax error at or near "SELECT" at character
    487", e infelizmente não conseguimos achar o que esta errado, dai peço
    ajuda aos colegas. Segue abaixo a procedure:


Legal isso...

Vamos por partes (como diria "Jack")...

    CREATE OR REPLACE FUNCTION TRAVA_INADIMPLENTES (
      DIAS_VENCIDO INTEGER,
      UND_LOCAL VARCHAR(3),
      CNPJ VARCHAR(18))
    RETURNS BOOLEAN
    AS
    $$
    DECLARE

    pDIAS_VENCIDO ALIAS FOR $1;
    pUND_LOCAL ALIAS FOR $2;
    pCNPJ ALIAS FOR $3;

    sPERMITE_BLOQUEIO VARCHAR(1);
    sFAT_DOCUMENTO VARCHAR(2);
    sFAT_EMISSORA VARCHAR(3);
    iFAT_NUMERO INTEGER;
    sFAT_ANO VARCHAR(2);
    iFAT_PARCELA INTEGER;
    sCOD_CLIENTE VARCHAR(18);
    iNRO_REGISTROS INTEGER;
    BEGIN


Até aqui esta OK...

     IF ( pCNPJ = '' ) THEN
     BEGIN


Veja a sintaxe do IF em plpgsql:
http://www.postgresql.org/docs/8.3/interactive/plpgsql-control-structures.html#PLPGSQL-CONDITIONALS

        FOR
           SELECT COB.TIPO_DOC, COB.FIL_ORIG, COB.FATURA, COB.ANO,
    COB.PARCELA, COB.CGC
           FROM CTAS_RECEBER COB
           WHERE ( COB.STATUS NOT IN ( 'CA', 'CO' )) AND ( COB.DT_PAGTO IS
    NULL )
             AND (( CURRENT_TIMESTAMP - COB.DT_VENCTO ) >= pDIAS_VENCIDO )
           ORDER BY COB.DT_VENCTO, COB.TIPO_DOC, COB.FIL_ORIG, COB.FATURA,
    COB.ANO
           INTO sFAT_DOCUMENTO, sFAT_EMISSORA, iFAT_NUMERO, sFAT_ANO,
    iFAT_PARCELA, sCOD_CLIENTE
        DO
        BEGIN


Veja a sintaxe do FOR em plpgsql:
http://www.postgresql.org/docs/8.3/interactive/plpgsql-control-structures.html#PLPGSQL-RECORDS-ITERATING

           SELECT CLI.PERMITE_PROTESTO
           FROM CLIENTES CLI
           WHERE CLI.CGC = sCOD_CLIENTE
           INTO sPERMITE_BLOQUEIO;

           IF (sPERMITE_BLOQUEIO = 'T') THEN
           BEGIN
              UPDATE CLIENTES CLI
              SET CLI.INADIMPLENTE = 'T', CLI.OPERADOR = 'BLOQUEIO
    AUTOMATICO', CLI.DT_ALTERACAO = CURRENT_TIMESTAMP
              WHERE CLI.CGC = sCOD_CLIENTE;

              INSERT INTO HIST_COBRANCA
              VALUES ( sFAT_DOCUMENTO, sFAT_EMISSORA, iFAT_NUMERO,
    sFAT_ANO, iFAT_PARCELA, CURRENT_TIMESTAMP, pUND_LOCAL,
                       'BLOQUEIO AUTOMATICO DE INADIMPLENTE', 'BLOQUEIO
    AUTOMATICO', CURRENT_TIMESTAMP );
           END IF;
        END
     END IF
     ELSE
     BEGIN

Aqui novamente precisas olhar a sintaxe do "IF" em plpgsql:
http://www.postgresql.org/docs/8.3/interactive/plpgsql-control-structures.html#PLPGSQL-CONDITIONALS

        FOR
           SELECT COB.TIPO_DOC, COB.FIL_ORIG, COB.FATURA, COB.ANO,
    COB.PARCELA, COB.CGC
           FROM CTAS_RECEBER COB
           WHERE ( COB.STATUS NOT IN ( 'CA', 'CO' )) AND ( COB.DT_PAGTO IS
    NULL )
            AND (( CURRENT_TIMESTAMP - COB.DT_VENCTO ) >= pDIAS_VENCIDO )
            AND ( COB.CGC = pCNPJ )
           ORDER BY COB.DT_VENCTO, COB.TIPO_DOC, COB.FIL_ORIG, COB.FATURA,
    COB.ANO
           INTO sFAT_DOCUMENTO, sFAT_EMISSORA, iFAT_NUMERO, sFAT_ANO,
    iFAT_PARCELA, sCOD_CLIENTE
        DO
        BEGIN
           SELECT CLI.PERMITE_PROTESTO
           FROM CLIENTES CLI
           WHERE CLI.CGC = sCOD_CLIENTE
           INTO sPERMITE_BLOQUEIO;


Aqui precisas verificar a atribuição do retorno de um SELECT:
http://www.postgresql.org/docs/8.3/interactive/plpgsql-statements.html#PLPGSQL-STATEMENTS-ASSIGNMENT

Creio que esse teu SELECT não irá funcionar com o INTO no final... pela documentação ele tem que estar antes da cláusula FROM...


           IF (sPERMITE_BLOQUEIO = 'T') THEN
           BEGIN
              UPDATE CLIENTES CLI
              SET CLI.INADIMPLENTE = 'T', CLI.OPERADOR = 'BLOQUEIO
    AUTOMATICO', CLI.DT_ALTERACAO = CURRENT_TIMESTAMP
              WHERE CLI.CGC = sCOD_CLIENTE;

              SELECT COUNT( HIS.FAT_NUMERO )
              FROM HIST_COBRANCA HIS
              WHERE ( HIS.FAT_DOCUMENTO = sFAT_DOCUMENTO ) AND (
    HIS.FAT_EMISSORA = sFAT_EMISSORA ) AND ( HIS.FAT_NUMERO =
    iFAT_NUMERO )
               AND ( HIS.FAT_ANO = sFAT_ANO ) AND ( HIS.FAT_PARCELA =
    iFAT_PARCELA ) AND ( HIS.DTA_LANCAMENTO = CURRENT_TIMESTAMP )
              INTO iNRO_REGISTROS;

              IF (iNRO_REGISTROS = 0) then
           BEGIN
             INSERT INTO HIST_COBRANCA
             VALUES ( sFAT_DOCUMENTO, sFAT_EMISSORA, iFAT_NUMERO,
    sFAT_ANO, iFAT_PARCELA, CURRENT_TIMESTAMP, pUND_LOCAL,
                      'BLOQUEIO AUTOMATICO DE INADIMPLENTE', 'BLOQUEIO
    AUTOMATICO', CURRENT_TIMESTAMP );
           END
        END
      END
     END


     RETURN TRUE;
    END;
    $$

    LANGUAGE 'plpgsql';


Pelo que percebi é só uma questão de adaptar os teus IFs, FORs e o retorno do SELECT pela sintaxe adequada em plpgsql... Se tiveres mais dúvidas manda ai...

Cordialmente,

--
Fabrízio de Royes Mello
>> Blog sobre PostgreSQL: http://fabriziomello.blogspot.com
------------------------------------------------------------------------

_______________________________________________
pgbr-geral mailing list
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral



__________ Information from ESET NOD32 Antivirus, version of virus signature 
database 4014 (20090416) __________

The message was checked by ESET NOD32 Antivirus.

http://www.eset.com




__________ Information from ESET NOD32 Antivirus, version of virus signature 
database 4016 (20090417) __________

The message was checked by ESET NOD32 Antivirus.

http://www.eset.com

_______________________________________________
pgbr-geral mailing list
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral

Responder a