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