[SQL] 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 ) 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; 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 -- Sent via pgsql-sql mailing list ([email protected]) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-sql
Re: [SQL] Problemas com Procedure no PostgreSQL
Bom dia. ... 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: ... 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 -- Sent via pgsql-sql mailing list ([email protected]) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-sql
Re: [SQL] Problemas com Procedure no PostgreSQL
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ço Refiz 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 é vantajoso 2. 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 if 3. 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 envolvidos Cumprimentos, Hélder M. Vieira 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';
Re: [SQL] Problemas com Procedure no PostgreSQL
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
Re: [SQL] Problemas com Procedure no PostgreSQL
cela , 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
Re: [SQL] How to count from a second table in an aggregate query?
Date: Wed, 15 Apr 2009 21:23:04 -0700 From: Steve Midgley To: Erik Jones Subject: Re: How to count from a second table in an aggregate query? Message-ID: <[email protected]> Erik Jones wrote: > > On Apr 15, 2009, at 1:15 PM, Steve Midgley wrote: > >> I want to generate an analysis report that counts the values in two >> separate tables. I've been able to accomplish what I want with two >> separate queries that I then merge together in Excel. Essentially >> what I need is a "horizontal UNION" statement (or something like that). >> >> get a FK id and count of a certain column in one table, based on some >> criteria >> -> for each FK id, get the count of a different column in a different >> table >> Display the counts from both queries side-by-side along with the FK >> id's in a single result set > > Joining against a subquery for the second count does the trick: > > select src_contact_id, count(log_type), cp.count > from contact_log , > (select contact_id, count(property_id) > from contact_property > group by contact_id) as cp > where src_contact_id = cp.contact_id > and log_type in ('web', 'detail') > group by src_contact_id, cp.count > order by src_contact_id > > src_contact_id | count | count > +---+--- > 1 | 5 | 4 > 2 | 3 | 2 > A friend of mine off-list provided an alternative SQL version which I thought the list might have interest in: select src_contact_id, count(distinct contact_log.id), count(distinct contact_property.id) from contact_log, contact_property where contact_log.src_contact_id = contact_property.contact_id and contact_log.log_type in ('web', 'detail') group by src_contact_id; Credit to Matt Gainsborough for that one. Makes perfect sense as I look at it. It's nice to see two alternate paths to the same solution. ANSI-92 joins work just as well as his ANSI-89 join syntax for this (i.e. using the "JOIN" keyword to set the relation). Steve
