[SQL] Problemas com Procedure no PostgreSQL

2009-04-17 Thread Paulo (O2 Tecnologia)



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

2009-04-17 Thread Hélder M . Vieira


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

2009-04-17 Thread Hélder M . Vieira
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

2009-04-17 Thread Paulo (O2 Tecnologia)
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

2009-04-17 Thread Paulo (O2 Tecnologia)
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?

2009-04-17 Thread Steve Midgley

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