Erro com Soterd Procedure, Sum, inner join e group by

Firebird

25/01/2009

Boa Tarde a todos do Forum :)
Estou com uma dúvida que esta me atormentando.
Não estou conseguindo fazer uma stored procedure de inserção em uma tabela, é o mesmo esquema de um cartão de crédito, verifica se o cliente possui saldo na conta, caso não possua não deixa inserir, neste caso verifica o valor da conta do cliente se pode inserir o débito.
Está muito difícil, já tentei de mil maneiras,mas não sai.
Utilizo Firebird 2.1 + Delphi7+IBExpert
Estou utilizando sum com inner join, mas dá o seguinte erro:
Invalid token.
Dynamic SQL Error.
SQL error code = -104.
Invalid expression in the select list (not contained in either an aggregate function or the GROUP BY clause).
Solicito ajuda da lista na solução.
Segue as duas tabelas:

[color=blue:03834953c6]CREATE TABLE COMPRA (
CORDEM INTEGER NOT NULL,
CCODCARTAO DMCARTAO NOT NULL /* DMCARTAO = BIGINT NOT NULL CHECK (VALUE = ´1111111111111111´ OR (VALUE > ´1111111111111111´ AND VALUE <= ´9999999999999999´ )) */,
CCODEMPRESA INTEGER NOT NULL,
CDATACOMPRA DMDATACAD NOT NULL /* DMDATACAD = TIMESTAMP DEFAULT ´NOW´ */,
CDESCRICAO DMNOMEGERAL /* DMNOMEGERAL = VARCHAR(60) CHECK (VALUE = UPPER (VALUE)) */,
CPARCELA DMPARCELAS NOT NULL /* DMPARCELAS = SMALLINT DEFAULT 1 CHECK (VALUE = 1 OR (VALUE > 1 AND VALUE <= 12)) */,
CVALOR NUMERIC(9,2) NOT NULL,
CDATAVENCIMENTO DATE DEFAULT ´NOW´ NOT NULL
);[/color:03834953c6]

[color=blue:03834953c6]CREATE TABLE CARTAO (
CACODIGO DMCARTAO NOT NULL /* DMCARTAO = BIGINT NOT NULL CHECK (VALUE = ´1111111111111111´ OR (VALUE > ´1111111111111111´ AND VALUE <= ´9999999999999999´ )) */,
CACODIGORH SMALLINT NOT NULL,
CANOMECARTAO VARCHAR(28) NOT NULL,
CASITUACAO DMSITUACAO NOT NULL COLLATE WIN_PTBR /* DMSITUACAO = VARCHAR(1) DEFAULT ´A´ CHECK (VALUE IN (´A´, ´B´, ´C´, ´I´)) */,
CAMAXSALARIO NUMERIC(9,2) NOT NULL,
CABONUS NUMERIC(6,2) NOT NULL,
CAMAXGASTO COMPUTED BY (CAMAXSALARIO + CABONUS),
CAFTIPOEMPRESA VARCHAR(2) NOT NULL,
CAORGAO SMALLINT NOT NULL,
CASENHA CHAR(7) NOT NULL,
CAVENCIMENTO DATE DEFAULT ´NOW´ NOT NULL
);[/color:03834953c6]
E a procedure:
CREATE OR ALTER PROCEDURE SP_INSERE_COMPRA (
ecodcartao bigint,
ecodempresa integer,
ecdatacompra timestamp,
ecdescricao char(60) character set win1252,
ecparcela smallint,
ecvalor numeric(9,2),
ecdatavencimento date,
emes smallint,
eano smallint,
ecvalorsoma numeric(9,2),
emesaux smallint,
eanoaux smallint)
returns (
ecodcartaosaida bigint,
edatavencsaida timestamp,
evalorsaida numeric(9,2))
as
begin
emes = extract(month from :ecdatavencimento);
eano = extract(year from :ecdatavencimento);
/*esta parte esta me matando, é aqui que que não sai*/ :?
[color=red:03834953c6] if (exists (select c.ccodcartao, sum(c.cvalor), c.cdatavencimento, t.camaxgasto
from compra c inner join cartao t
on c.ccodcartao = t.cacodigo
where (ccodcarta o = :ecodcartao) and (extract(month from cdatavencimento) = :emes)
and (extract(year from cdatavencimento) = :eano))) then[/color:03834953c6]
begin
if (c.cvalor+ecvalor > t.camaxgasto ) then
exception incluir_compra;
else
if (c.cvalor+ecvalor <= t.camaxgasto ) then
insert into compra(
cordem,
ccodcartao,
ccodempresa,
cdatacompra,
cdescricao,
cparcela,
cvalor,
cdatavencimento)
values (
gen_id(gen_compra_id,1),
:ecodcartao,
:ecodempresa,
:ecdatacompra,
:ecdescricao,
:ecparcela,
:ecvalor,
:ecdatavencimen to);
end
end

Agradeço a ajuda de todos,


Ravascon

Ravascon

Curtidas 0

Respostas

Webjoel

Webjoel

25/01/2009

Olá!

seu problema está no select, você está usando uma expressa de soma (sum), e quando se usa essa ou outras expressões como ´count´ tem-se a necessidade de usar o group by no final do select, determinando o agrupamento da soma de valores que você tem a intensão de pegar, segue abaixo o select com a correção:

select

c.ccodcartao,
sum(c.cvalor),
c.cdatavencimento,
t.camaxgasto

from compra c
inner join cartao t on c.ccodcartao = t.cacodigo
where (ccodcarta o = :ecodcartao)
and (extract(month from cdatavencimento) = :emes)
and (extract(year from cdatavencimento) = :eano)

group by c.ccodcartao, c.cdatavencimento, t.camaxgasto



GOSTEI 0
Ravascon

Ravascon

25/01/2009

Cito:
[color=green]Código: 

select 

c.ccodcartao, 
sum(c.cvalor), 
c.cdatavencimento, 
t.camaxgasto 

from compra c 
inner join cartao t on c.ccodcartao = t.cacodigo 
where (ccodcarta o = :ecodcartao) 
and (extract(month from cdatavencimento) = :emes) 
and (extract(year from cdatavencimento) = :eano) 

group by c.ccodcartao, c.cdatavencimento, t.camaxgasto [/color]


Caro amigo, obrigado pela resposta deu certo, era isto mesmo :D
Precisar estamos ai :wink:


GOSTEI 0
POSTAR