Thread: Problemas com Procedure no PostgreSQL
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: 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 IF ( pCNPJ = '' ) THEN BEGIN 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 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 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 ) ORDERBY 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; 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'; __________ Information from ESET NOD32 Antivirus, version of virus signature database 4014 (20090416) __________ The message was checked by ESET NOD32 Antivirus. http://www.eset.com
Bom dia. ... >acusado o seguinte erro "sintax error at or near "SELECT" at character 487", e infelizmente não conseguimos achar o queesta >errado, dai peço ajuda aos colegas. Segue abaixo a procedure: ... > IF ( pCNPJ = '' ) THEN > BEGIN ... > END IF ... Numa leitura sumária, parece-me que há vários problemas neste procedimento. Desde logo, a condição tem estrutura inválida: IF ... THEN BEGIN ... END IF Deverá ser substituída por ( atenção ao ponto e vírgula após o END IF ) : IF ... THEN ... END IF; P.f. experimente essa alteração e, caso continue a ter problemas, volte a publicar aqui o script na sua nova redacção. Já agora, quando publicar mensagens nesta lista, caso lhe seja possível escreva em inglês. Cumprimentos, Helder M. Vieira
> 487", e infelizmente não conseguimos achar o que esta errado, dai peço
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 sfat_documento ,
fil_orig as sfat_emissora ,
fatura as ifat_numero ,
ano as sfat_ano ,
parcela as ifat_parcela ,
cgc as scod_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.scod_cliente
into spermite_bloqueio;
if (spermite_bloqueio = 't') then
--
update clientes
set inadimplente = 't' ,
operador = 'bloqueio automatico' ,
dt_alteracao = current_timestamp
where cgc = rdat.scod_cliente;
--
insert into hist_cobranca
values ( rdat.sfat_documento, rdat.sfat_emissora, rdat.ifat_numero, rdat.sfat_ano, rdat.ifat_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 sfat_documento ,
fil_orig as sfat_emissora ,
fatura as ifat_numero ,
ano as sfat_ano ,
parcela as ifat_parcela ,
cgc as scod_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 = scod_cliente
into spermite_bloqueio;
if ( spermite_bloqueio = 't' ) then
--
update clientes
set inadimplente = 't' ,
operador = 'bloqueio automatico' ,
dt_alteracao = current_timestamp
where cgc = scod_cliente;
--
select count( fat_numero )
from hist_cobranca
where ( fat_documento = rdat.sfat_documento )
and ( fat_emissora = rdat.sfat_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.sfat_documento, rdat.sfat_emissora, rdat.ifat_numero, rdat.sfat_ano, rdat.ifat_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';
Funcionou 110%, o problema é conceitual, ainda estamos com pensando na forma procedural do Firebird, nele não há necessidade do record, mas estamos aprendendo e em breve estaremos agregando ajuda a lista.
Obrigado mesmo.
Paulo Santana
O2 Tecnologia em Sistemas
Hélder M. Vieira escreveu:
Boa tarde.> 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çoRefiz todo o texto, p.f. experimente e diga se resultou.Algumas das alterações que fiz são meramente estilísticas, outras têm a ver com questões gramaticais. As mais significativas são:1. Transcrição para minúsculas. Do ponto de vista dos comandos plpgsql julgo que é indiferente, mas o uso de maiúsculas para nomear objectos no Postgres não é vantajoso2. Declaração de parâmetros. Os alias já não são necessários, os parâmetros podem ser utilizados por nome em vez de $1, $2, etc...2. Correcção das estruturas if .. then .. end if3. Reformulação dos ciclos for .. in .. loop .. end loop, que passam a usar uma variável de tipo registo ( declarada como 'rdat record' )4. Supressão de alias nos select e update, uma vez que não há join envolvidosCumprimentos,Hélder M. Vieiracreate 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 sfat_documento ,
fil_orig as sfat_emissora ,
fatura as ifat_numero ,
ano as sfat_ano ,
parcela as ifat_parcela ,
cgc as scod_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.scod_cliente
into spermite_bloqueio;
if (spermite_bloqueio = 't') then
--
update clientes
set inadimplente = 't' ,
operador = 'bloqueio automatico' ,
dt_alteracao = current_timestamp
where cgc = rdat.scod_cliente;
--
insert into hist_cobranca
values ( rdat.sfat_documento, rdat.sfat_emissora, rdat.ifat_numero, rdat.sfat_ano, rdat.ifat_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 sfat_documento ,
fil_orig as sfat_emissora ,
fatura as ifat_numero ,
ano as sfat_ano ,
parcela as ifat_parcela ,
cgc as scod_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 = scod_cliente
into spermite_bloqueio;if ( spermite_bloqueio = 't' ) then
--
update clientes
set inadimplente = 't' ,
operador = 'bloqueio automatico' ,
dt_alteracao = current_timestamp
where cgc = scod_cliente;
--
select count( fat_numero )
from hist_cobranca
where ( fat_documento = rdat.sfat_documento )
and ( fat_emissora = rdat.sfat_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.sfat_documento, rdat.sfat_emissora, rdat.ifat_numero, rdat.sfat_ano, rdat.ifat_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';
__________ Information from ESET NOD32 Antivirus, version of virus signature database 4016 (20090417) __________
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
A function was so far:
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';
Thank you all for help,
Paulo Santana
O2 Tecnologia em Sistemas
Hélder M. Vieira escreveu:
Boa tarde.> 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çoRefiz todo o texto, p.f. experimente e diga se resultou.Algumas das alterações que fiz são meramente estilísticas, outras têm a ver com questões gramaticais. As mais significativas são:1. Transcrição para minúsculas. Do ponto de vista dos comandos plpgsql julgo que é indiferente, mas o uso de maiúsculas para nomear objectos no Postgres não é vantajoso2. Declaração de parâmetros. Os alias já não são necessários, os parâmetros podem ser utilizados por nome em vez de $1, $2, etc...2. Correcção das estruturas if .. then .. end if3. Reformulação dos ciclos for .. in .. loop .. end loop, que passam a usar uma variável de tipo registo ( declarada como 'rdat record' )4. Supressão de alias nos select e update, uma vez que não há join envolvidosCumprimentos,Hélder M. Vieiracreate 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 sfat_documento ,
fil_orig as sfat_emissora ,
fatura as ifat_numero ,
ano as sfat_ano ,
parcela as ifat_parcela ,
cgc as scod_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.scod_cliente
into spermite_bloqueio;
if (spermite_bloqueio = 't') then
--
update clientes
set inadimplente = 't' ,
operador = 'bloqueio automatico' ,
dt_alteracao = current_timestamp
where cgc = rdat.scod_cliente;
--
insert into hist_cobranca
values ( rdat.sfat_documento, rdat.sfat_emissora, rdat.ifat_numero, rdat.sfat_ano, rdat.ifat_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 sfat_documento ,
fil_orig as sfat_emissora ,
fatura as ifat_numero ,
ano as sfat_ano ,
parcela as ifat_parcela ,
cgc as scod_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 = scod_cliente
into spermite_bloqueio;if ( spermite_bloqueio = 't' ) then
--
update clientes
set inadimplente = 't' ,
operador = 'bloqueio automatico' ,
dt_alteracao = current_timestamp
where cgc = scod_cliente;
--
select count( fat_numero )
from hist_cobranca
where ( fat_documento = rdat.sfat_documento )
and ( fat_emissora = rdat.sfat_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.sfat_documento, rdat.sfat_emissora, rdat.ifat_numero, rdat.sfat_ano, rdat.ifat_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';
__________ Information from ESET NOD32 Antivirus, version of virus signature database 4016 (20090417) __________
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