Store Procedure meio complicada!

Firebird

09/10/2003

Olá amigos,
tenho que fazer o seguinte:
Tenho 4 tabelas:

Tabela A
cod_cliente
nome

Tabela B
cod_cliente
cod_produto

Tabela C
cod_produto
descricao

Tabela D
cod_produto
rev
custo

Depois de fazer uma busca por cod_produto, tenho que jogar o resultado num DBGRID com as seguintes colunas:

nome cod_produto descricao rev custo

Agora tenho algumas dúvidas:
- É melhor eu criar uma Store Procedure para realizar este trabalho para mim? Se for, como ficaria a SP?
- Depois de criada, como faço para chama-la em meu sistema?

muito obrigado pela atenção.


Anarchybra

Anarchybra

Curtidas 0

Respostas

Afarias

Afarias

09/10/2003

acho q um SELECT como abaixo resolve::

select a.nome, c.cod_produto, c.descricao, d.rev, d.custo
from tabela_a a, tabela_b b, tabela_c c
where a.cod_cliente = b.cod_cliente
and b.cod_produto = c.cod_produto
and d.cod_produto = b.cod_produto

ou

select a.nome, c.cod_produto, c.descricao, d.rev, d.custo
from tabela_a a
inner join tabela_b b on (b.cod_cliente = a.cod_cliente)
inner join tabela_c c on (c.cod_produto = b.cod_produto)
inner join tabela_d d on (d.cod_produto = c.cod_produto)


T+


GOSTEI 0
Anarchybra

Anarchybra

09/10/2003

Mais uma vez, muito obrigado Afarias.
Sem querer incomodar, poderia tirar uma outra dúvida?
Tenho que calcular o campo d.rev que é do tipo NUMERIC.
como faço para desse número subtrair 2,20, ou seja:
d.rev - 2,20

Muito obrigado novamente.


GOSTEI 0
Afarias

Afarias

09/10/2003

|como faço para desse número subtrair 2,20, ou seja: d.rev - 2,20

faça a operação normalmente. só lembre q o separador decimal é ponto (.) e não vírgula::


select a.nome, c.cod_produto, c.descricao, (d.rev - 2.20) as rev, d.custo
{...}


T+


GOSTEI 0
Edison_br

Edison_br

09/10/2003

vc tambem pode criar uma View.
Geralmente se utiliza stored procedure qdo vc quer retornar algum valor ex: Um novo código, Total de um pedido ou para fazer algum calculo.


GOSTEI 0
Anarchybra

Anarchybra

09/10/2003

Muito obrigado pela ajuda amigos Afarias e Edison_br.
Vocês poderiam me ajudar com uma última dúvida?
Como faço para formatar um campo no select?
Por exemplo, eu tenho o seguinte:
select a.nome,c.cod_produto, c.descricao, d.revisao, d.custo, ((d.custo / 2.20)*100-100) from a,c,d
mas ele me volta números como 1,239923445322...
como faço para formatar este resultado com apenas duas casas decimais neste select?

Muito obrigado mais uma vez.


GOSTEI 0
Anarchybra

Anarchybra

09/10/2003

Valeu amigos...
eu já consegui... pura besteira minha.... esqueci do DisplayFormat.


GOSTEI 0
Edison_br

Edison_br

09/10/2003

desculpe a demora mas se eu entendi algo assim ou parecido com isto deve funcionar.
select a.nome,c.cod_produto, c.descricao, d.revisao, d.custo,
cast(((d.custo / 2.20)*100-100) as numeric(8,2)) from a,c,d

att Edison


GOSTEI 0
Anarchybra

Anarchybra

09/10/2003

Olá amigos,
me surgiu uma outra dúvida....
eu tenho várias alterações no campo c.cod_produto, que são como atualizações. A atualização que vale realmente, a atual, é sempre a maior.
Por exemplo: atualização 1,2,3 a atual será a 3.
o campo atualização esta na tabela B e quando eu fazer a consulta pelo cod_produto ele terá que trazer apenas a última atualização.
Exemplo:
produto 1 atualização 1
produto 1 atualização 2
.................................
eu preciso que ele só me traga:
produto 1 atualização 2

eu tentei usar o MAX mas acho que incrementei errado, pois sempre dá erro...
será que poderiam me ajudar?

Muito obrigado.


GOSTEI 0
Afarias

Afarias

09/10/2003

select produto, max(atualizacao) from tabela
group by produto


ou, se for para apenas um produto específico::

select max(atualizacao) from tabela
where produto = x


T+


GOSTEI 0
Anarchybra

Anarchybra

09/10/2003

Perfeito AFarias,
o que digo é colocar esta instrução naquela primeira que você me passou, isto é que eu não estou conseguindo...


GOSTEI 0
Afarias

Afarias

09/10/2003

primeiro crie uma VIEW ::

create view ultimas_atualizacoes (produto, atualizacao) as
select produto, max(atualizacao) from tabela
group by produto


depois insira a view no JOIN ::

select a.nome, c.cod_produto, c.descricao, d.rev, d.custo, u.atualizacao
from tabela_a a
inner join tabela_b b on (b.cod_cliente = a.cod_cliente)
inner join tabela_c c on (c.cod_produto = b.cod_produto)
inner join tabela_d d on (d.cod_produto = c.cod_produto)
inner join ultimas_atualizacoes u on (u.produto = b.cod_produto)


T+


GOSTEI 0
Anarchybra

Anarchybra

09/10/2003

Afaris, obrigado pela atenção...
mas ele me reotrnou o seguinte erro:

[b:fa3ec80ec9]No argument for format ´¬s´[/b:fa3ec80ec9]

O que estou fazendo de errado?


GOSTEI 0
Afarias

Afarias

09/10/2003

|mas ele me reotrnou o seguinte erro: No argument for format ´¬s´
|O que estou fazendo de errado?

não sei! só sei q não tem nada com o IB!! ...isso é erro do Delphi (provavelmente do uso da função Format) e sem ver seu código não dá pra dizer.


T+


GOSTEI 0
Anarchybra

Anarchybra

09/10/2003

A instrução é a seguinte:

select a.nome, c.descricao, d.custo, ((d.custo / 2.20)*100-100), u.revisao
from cliente a
inner join b b on (b.cod_cliente = a.cod_cliente)
inner join c c on (c.cod_produto = b.cod_formula)
inner join d d on (d.cod_formula = c.cod_produto)
inner join ultima_atualizacao u on (u.cod_produto = c.cod_produto)
where produto.cod_produto like ´¬BR¬´


GOSTEI 0
Afarias

Afarias

09/10/2003

vc rodou esse código no IBConsole??

acredito q roda normalmente (bom, rodaria se não tivesse erros de sintaxe como o nome das tabelas q não estão ai (está ´b b´, ´c c´, etc...))!!

como disse, o ERRO é no seu código no DELPHI.


T+


GOSTEI 0
Anarchybra

Anarchybra

09/10/2003

Amigo Afarias,
estou quase conseguindo....
No meu código em Delphi tenho o seguinte:

select a.nome, a.cod_cliente, c.descricao, c.cod_produto, d.custo, ((d.custo / 2.20)*100-100), e.atualizacao
from a, b, c, d, e
where b.cod_cliente = a.cod_cliente
and c.cod_produto = b.cod_formula
and d.cod_formula = c.cod_produto
and c.cod_produto = ´1121´
and e.atualizacao = (select max(atualizacao) from e)

Ele me retorna quase tudo o que eu quero, em vez dele retornar a atualização do respectivo produto ele me retorna o maior valor da tabela, que é 11.
Só me falta isso... como faço para mostrar pra ele que o campo e.atualizacao depende do c.produto (no delphi).
Mais uma vez, muito obrigado pela atenção Afarias. E me desculpe a amolação. :(
P.S: Estou a 9 meses desenvolvendo este programa e só me falta isso para poder entregar. É mole?
Só falta isso... como eu mostro pra ele que


GOSTEI 0
Afarias

Afarias

09/10/2003

bom... sem seguir uma linha não fica fácil...

vc estava dizendo q estava com erro -- agora já diz q (ao q entendi) sua SQL não retorna os valores q vc precisa.

vc então passa um código SQL dizendo q está no Delphi -- mas como?? está em um componente query é?!!?

Bom, defina claramente qual seu problema e ai podemos tentar resolver. se sua SQL não retorna o q vc quer, passe os dados da implementação de suas tabelas/relacionamentos e diga o q precisa (o resultado) -- dai podemos tentar construir um SQL que lhe sirva.



T+


GOSTEI 0
Anarchybra

Anarchybra

09/10/2003

Me desculpe, acho que me empolguei e compliquei um pouco.
Voltando tudo...
Tenho a tabela A (cliente)
B (produto_cliente)
C (produto)
D (atualizacao_ativa)
E (custo)
F (uma view que eu crie com os campos A.Nome, B.cod_produto, B.descricao, C.cod_produto, C.descricao, D.cod_produto, D.atualizacao, E.custo)

Os produtos são atualizados frequentemente, portante na tabela está o nível atual de sua atualização (1,2,3,4...). A última atualização é sempre a ativa.
Tenho que realizar uma busca (por produto ou código) que me traga:
- Nome do cliente
- Código do produto
- Descrição do Produto
- Atualização
- Custo

Como você já me havia dito Afarias, com suas dicas (que agradeço muito) eu consegui trazer estes resultados... só que a atualização estava errada, pois ela buscava sempre a maior atualização da tabela e não do produto (select max(atualizacao) from atualizao_ativa).
Este sistema precisaria ser entregue na sexta-feira.... confesso que sou novo na área, mas dou meus pulos com livros e apostilas.... mas não achei solução para o meu problema.
Você poderia me dar uma luz?
Ficarei muito agradecido.

muito obrigado.


GOSTEI 0
Afarias

Afarias

09/10/2003

:(

continua difícil ajudar... vc me passou o nome das tabelas mas não os campos (pelo menos os principais) para ver como esse seu lance funciona... não estou entendendo seu problema mas vou dar uns ´chutes´ ::

já q a tabela D (atualizacao_ativa) tem os campos PRODUTO e ATUALIZACAO ... vc pode fazer::

select max(atualizacao) from atualizacao_ativa
where produto = :tal_produto

ou

select produto, max(atualizacao) from atualizacao_ativa
group by produto


blz?!?!


o q vc pode fazer tb é criar um campo ULTIMA_ATUALIZACAO na tabela PRODUTO e ter uma trigger na tabela ATUALIZACAO_ATIVA que atualize este valor, ex::

set term ^;

create trigger DefineAtualizacaoProduto for ATUALIZACAO_ATIVA
after insert as
begin
update PRODUTO
set ULTIMA_ATUALIZACAO = new.ATUALIZACAO
where codigo = new.COD_PRODUTO;
end^


desta forma basta consultar a tabela PRODUTO para verificar qual sua última atualização.



T+


GOSTEI 0
Anarchybra

Anarchybra

09/10/2003

me desculpe novamente AFarias, estou tentando implementar o código que me passou...

Os campos da tabela são:

Tabela A (Cliente)
Cod_cliente
Nome

Tabela B (atualizacao_cliente)
Cod_cliente
Cod_produto
Descricao

Tabela C (produto)
Cod_produto
Descricao

Tabela D (atualizacao_ativa)
Cod_produto
Atualizacao

Tabela E (Custo)
Cod_produto
Custo

Tabela F (view vw_atualizacao)
- Cod_produto
- Descricao
- Atualizacao

Estes são os campos que vou usar das tabelas....

Quando abro o respectivo formulário ele carrega uma Query num DBGrid que de imediato mostra todos os produtos e suas respectivas atualizacoes ativas.
Tenho um TEdit, onde coloquei uma busca em seu evento OnKeyPress que faz a busca pelo produto escolhido pelo usuário. Também tenho umTComboBox com uma lista de Categorias. Quando o usuário escolhe uma certa categoria de produto, ele faz a pesquisa correspondente e traz todos os produtos que se enquadram. Enquanto a isso moleza, o que está me atrapalhando é mesmo a instrução SQL da Query e via programação.

Me perdoe pela insistência, mas necessito.
Muito obrigado novamente.


GOSTEI 0
Anarchybra

Anarchybra

09/10/2003

Amigo Afarias, resumindo ao máximo, eu tenho este código:

[b:c32cc96b7b]select cliente.nome, produto.descricao, produto.cod_produto, rev_custo.custo, ((rev_custo.custo / 2.20)*100-100)
from cliente a
inner join produto_cliente b on (produto_cliente.cod_cliente = cliente.cod_cliente)
inner join produto c on (produto.cod_produto = produto_cliente.cod_produto)
inner join rev_custo d on (rev_custo.cod_produto = produto.cod_produto)
where produto.cod_produto like ´¬BR¬´[/b:c32cc96b7b]

e gostaria de implementar este último código que me passou.

[b:c32cc96b7b]select cod_produto, max(atualizacao) from vw_atualizacao
where cod_produto like ´¬BR¬´
group by cod_produto[/b:c32cc96b7b]
Isso é tudo Afarias, quero fazer a junção destes dois códigos. Com a junção dos códigos, quando o usuário procurar por um produto a consulta irá retornar o produto e seus devidos campos (definidos no primeiro código) e com a atualizacao atual. É isso que eu quero.

Se puder me ajudar.
estou quebrando a cabeça aqui. :oops:


GOSTEI 0
Afarias

Afarias

09/10/2003

rapaz... eu acho q já falamos nisso algumas mensagens atras... vamos voltar ao caso::

primeiro crie uma VIEW ::

create view ultimas_atualizacoes (produto, atualizacao) as
select produto, max(atualizacao) from atualizacao_ativa
group by produto


depois insira a view no JOIN ::

select a.nome, c.cod_produto, c.descricao, d.rev, d.custo, u.atualizacao
from tabela_a a
inner join tabela_b b on (b.cod_cliente = a.cod_cliente)
inner join tabela_c c on (c.cod_produto = b.cod_produto)
inner join tabela_d d on (d.cod_produto = c.cod_produto)
inner join ultimas_atualizacoes u on (u.produto = b.cod_produto)


espero q estejamos caminhando na mesma direção... :roll: ... e cuidado com a cabeça!! :D


T+


GOSTEI 0
Anarchybra

Anarchybra

09/10/2003

Eu mais uma vez AFarias,
fiz tudo o que pediu.....
coloquei minha query para ser aberta junto o DataModule, e me dava [b:789b662233]´No format ¬s´[/b:789b662233]

Depois eu fiz diferente, não carreguei a Query no início, deixar sem carregar e me apareceu o erro [b:789b662233]´List index out of bounds (5)´[/b:789b662233]

E quando vou visualizar minha View no IBConsole, ele gera o erro [b:789b662233]´Invalid Database key´ [/b:789b662233], mas quando a uso para fazer algum tipo de pesquisa ela me retorna um resultado satisfatório... isso é normal?

Estou explodindo de tanta dor de cabeça... :oops:


GOSTEI 0
Afarias

Afarias

09/10/2003

|fiz tudo o que pediu.....

Rapaz... não tô crendo nisso não... pra mim vc não ´ouviu´ metade do que falei até aqui...


|coloquei minha query para ser aberta junto o DataModule, e me
|dava ´No format ¬s´ {...}

Olha ai... ainda o problema do Format... já comentei sobre uso da função Format... e?!?! continua o erro e eu não tenho a mínima noção do seu código!

Olha cara... presta atenção::

ESSES ERROS NÃO TEM NADA QUE VER COM O SQL Q TE PASSEI (ou qualquer outra coisa q discutimos até agora)!!!!

ou discutimos a solução ou os erros -- uma hora vc fala q não obtem o resultado esperado, outra hora q dá erro -- tá ruim!!

Eu já te disse:: OS ERROS SÃO DO SEU CÓDIGO DELPHI!!!! (coisa q em momento algum vc postou aqui!!)


|E quando vou visualizar minha View no IBConsole, ele gera o
|erro ´Invalid Database key´ , mas quando a uso para fazer algum tipo
|de pesquisa ela me retorna um resultado satisfatório... isso é normal?

Não... atualize seu IBConsole. Vc está usando q versão do IB?? ou está usando FB?? (qual versão??)

Verifique tb se seu banco de dados não está corrompido.


|Estou explodindo de tanta dor de cabeça

vá relaxar... pegue uma praia, saia com a namorada e só volte daqui 1 ou 2 dias... vc provavelmente terá mais condições de resolver o problema...


( ...se vc não fizer isso quem vai fazer sou eu!! ;-) )


T+


GOSTEI 0
Anarchybra

Anarchybra

09/10/2003

valeu Afarias, muito obrigado pela sua atenção....
Vou ver o que faço aqui...

Brigadão. :wink:


GOSTEI 0
Anarchybra

Anarchybra

09/10/2003

AFarias, uma última pergunta....

eu quero fazer uma View que com duas tabelas diferentes que pegue os maiores valores de dois campos, eu fiz o seguinte:

[b:3fc21a8dad]CREATE VIEW COMP_3
(
COD_FRML,
REV,
DT_REV
) AS

SELECT REV_CUSTO.COD_FORMULA, REV_CUSTO.REVISAO, REV_CUSTO.CUSTO, REV_CUSTO.DT_INICIO, REV_ATIVA.COD_FORMULA, REV_ATIVA.REVISAO
FROM REV_CUSTO, REV_ATIVA
WHERE REV_CUSTO.COD_FORMULA = REV_ATIVA.COD_FORMULA
AND REV_CUSTO.REVISAO = (SELECT MAX(REVISAO) FROM REV_ATIVA)
AND REV_CUSTO.DT_INICIO = (SELECT MAX(DT_INICIO) FROM REV_CUSTO)
GROUP BY REV_CUSTO.COD_FORMULA
;[/b:3fc21a8dad]

Quando eu retiro a instrução GROUP BY ele compila a VIEW, só que quando vou visualiza-la ela está vazia (NULL), se coloco a instrução GROUP BY ele não roda (INVALID COLUNM REFERENCE).

Como resolvo isso AFarias? É a última coisa que te peço e encerramos este assunto.


GOSTEI 0
Afarias

Afarias

09/10/2003

|Quando eu retiro a instrução GROUP BY ele compila a VIEW, só que
|quando vou visualiza-la ela está vazia (NULL), se coloco a instrução
|GROUP BY ele não roda (INVALID COLUNM REFERENCE).

Colocar o GROUP BY não vai fazer com q o SELECT traga registros... se não está trazendo registros, verifique os dados e a relação entre as tabelas (sua cláusula WHERE).

o GROUP BY está dando erro pois vc tem q colocar no GROUP BY *todos* os campos que NÃO estão em funções de grupo (no seu caso não tem nenhum campo sendo ´sumarizado´) -- então a sintaxe está incorreta -- tb está incorreto ter uma quantidade de campos no SELECT diferente da quantidade de campos definidos na VIEW.

Sugiro q vc dê uma lida com calma (a medida q vá precisando) nos guias de SQL do Interbase.

Não dá pra ajudar muito com os SQL pq: 1) não conheço suas tabelas e como estão relaciondas; 2) vc não diz o q precisa.


|É a última coisa que te peço e encerramos este assunto.

Não se preocupe em colocar suas questões no fórum... afinal, esta é a função do fórum -- apenas, procure colocar suas dúvidas de forma CLARA e PRECISA, seguindo sempre uma LINHA DE AÇÃO e fornecendo toda INFORMAÇÃO necessária para q, todos os colegas q acompanhem o fórum possam ajudar de forma útil.


T+


GOSTEI 0
Anarchybra

Anarchybra

09/10/2003

AFarias, muito obrigado pela força.
Resolvi meu problema.


GOSTEI 0
Afarias

Afarias

09/10/2003

Fico contente!! 8)


T+



PS: se ainda não tirou aquela folga q sugeri -- aproveite agora, vc merece ;-)


GOSTEI 0
POSTAR