Delphi + Mysql + Tabela Vendas x Itens_vendas

MySQL

Delphi

16/09/2016

Bom dia pessoal já procurei por ai até achei topicos com a mesma duvida mas nenhuma solução que me serve.

Tenho um sistema Delphi XE8 com Mysql 5 usando Componentes DBExpres. O que preciso parece simples mas não é.

Tenho uma tabela de VENDAS e outra ITENS_VENDAS. O campo que liga as duas tabelas é o ID_VENDA. Onde na tabela VENDA ele é Auto_Increment, pois bem.

Como obter o valor ID_VENDA, para lançar na tabela ITENS_VENDA antes de gravar no banco? ( o comando LAST_INSERT_ID() não funciona, ou então não sei usar, sempre retorna o valor 0).

Ahhh mas então vc da um post e depois pega o numero. OK mas e se o usuario desistir da venda? como desfaço o post?


Alguém tem um exemplo de como trabalhar no delphi com essa relação de tabelas?
Casa

Casa

Curtidas 0

Melhor post

Jones Granatyr

Jones Granatyr

16/09/2016

Olá,

Sobre essa parte: "OK mas e se o usuario desistir da venda? como desfaço o post?"

Poderia também verificar se existe algum item, caso não faz um delete na venda

Jones
GOSTEI 1

Mais Respostas

Huidemar Costa

Huidemar Costa

16/09/2016

Boa Tarde!
A forma que eu faria é salvar o "cabeçalho" da nota(Id_Venda, Numero, data, cliente/fornecedor), tendo feito isso terei o ID_VENDA, feito isso eu incluiria os itens da nota.

A tabela poderia ter um campo para dizer se a venda foi finalizada, caso não tenha sido finalizada, ou seja, o usuário desistiu da venda, ele exclui a Nota.
GOSTEI 0
Kellson

Kellson

16/09/2016

usa o comando Max(codigo)+1 acho que no mysql deve ser mesma logica que no sql
select Max(id) from cliente


ou


select @@identity as 'ULTIMOID' +1
GOSTEI 0
Kellson

Kellson

16/09/2016

vc deveria usar o CDS Virtual, assim vc pode manusear ate estornar antes de efetivar no banco de dados.
GOSTEI 0
Kellson

Kellson

16/09/2016

olha como eu faria, como id da venda gera uma unica vez com autoincrement, Identity, entao vc precisa fazer apenas um insert onde gera o id da venda e grava todos os itens com id da venda capturado certo.

faz um Virtual Clientdataset para armazenar os itens temporario, faça uma fct ou SP no proprio delphi para quando form lançando item ja somando para vc


botao finalizar
with query_venda do
begin
close;
sql.clear;
sql.text:='insert into venda(colunas) values( valores);
execsql;
sql.clear;
sql.text:='select Max(IVENDA) as ULTIMOID from venda;
VARIAVEL INTEGER OU STRING:=query.fieldbyname(ULTIMOID).value;
sql.clear;
sql.text:='select * from venda' // para nao dar exception not result
open;

end;

ate agora vc tem o id da venda

entao agora vem

while not(clientdataset.eof) do
begin


with query_ITEMVENDA do
begin
sql.add('insert into itemvenda(codigovenda,item,etc) values('+quotedstr(StringCodVenda)+',item,etc);
end;


clientdataset.next;
end



with adoquery_itemvenda do
begin
execsql;
end;




gambiarra pura kkkkkk, unica coisa que passou rapido pela minha cabeça, mas é claro se tiver fazendo na hora surge ideias melhores.
GOSTEI 0
Kellson

Kellson

16/09/2016

olha como eu faria, como id da venda gera uma unica vez com autoincrement, Identity, entao vc precisa fazer apenas um insert onde gera o id da venda e grava todos os itens com id da venda capturado certo.

faz um Virtual Clientdataset para armazenar os itens temporario, faça uma fct ou SP no proprio delphi para quando form lançando item ja somando para vc


botao finalizar
with query_venda do
begin
close;
sql.clear;
sql.text:='insert into venda(colunas) values( valores);
execsql;
sql.clear;
sql.text:='select Max(IVENDA) as ULTIMOID from venda;
open <--------------------------------------------------------------------------------------------------------------- // abrir para trazer o resultado
VARIAVEL INTEGER OU STRING:=query.fieldbyname(ULTIMOID).value;
close;
sql.clear;


end;

ate agora vc tem o id da venda

entao agora vem

while not(clientdataset.eof) do
begin


with query_ITEMVENDA do
begin
sql.add('insert into itemvenda(codigovenda,item,etc) values('+quotedstr(StringCodVenda)+',item,etc);
end;


clientdataset.next;
end



with adoquery_itemvenda do
begin
execsql;
end;




gambiarra pura kkkkkk, unica coisa que passou rapido pela minha cabeça, mas é claro se tiver fazendo na hora surge ideias melhores.
GOSTEI 0
Casa

Casa

16/09/2016

Mas para uma aplicação em rede onde dois ou mais usuários irão utilizar ao mmsm tempo nao da problema de violar a chave primaria?
GOSTEI 0
Kellson

Kellson

16/09/2016

nao da problema nao,pois so gera id quando o cliente requisita insert , entao o banco no servidor vai gerar o ID com o generator identity.
puts amigo nao tenho nenhum projeto, perdi meu HD com os projetos , porem ja fiz isso.
GOSTEI 0
Casa

Casa

16/09/2016

nao da problema nao,pois so gera id quando o cliente requisita insert , entao o banco no servidor vai gerar o ID com o generator identity.
puts amigo nao tenho nenhum projeto, perdi meu HD com os projetos , porem ja fiz isso.


Então fiz o teste aqui, e usar o comando MAX vai dar problema com a chave sim, ele só gera o id quando posta, se duas pessoas abrir uma venda ao memso tempo vai gerar o mesmo ID.

Consegue um exemplo pra mim?
GOSTEI 0
Raimundo Pereira

Raimundo Pereira

16/09/2016

Boa tarde,
Uma alternativa é Criar uma tabela temporária.

TMP_Venda
ID_VENDA,Usado

Então, abriu a tela de vendas a primeira coisa é gerar um id e salvar na TMP_VENDA.
O próximo usuário em rede irá gerar um novo ID.

O número fica resguardado, Após comitt basta realizar um updade USADO=SIM.
GOSTEI 0
Kellson

Kellson

16/09/2016

como vc fez? pois o sql aceita em seguimento os comandos não simultâneo na tabela, exemplo: executar comando 1 e comando 2

1 - insert +1 =2
2 - insert +1=3

e nao simultaneo 1,2
GOSTEI 0
Kellson

Kellson

16/09/2016

faz uma procedure então onde da um set var=Identity para pegar ultimo numero da do gerador assim inserindo nos itens
GOSTEI 0
Kellson

Kellson

16/09/2016

exemplo seria isso aqui : gerar proximo id com o proprio gerador do banco , pegar o ip da venda para utilizar nos itens, usa o identity para pegar ultimo id, e logo abaixo na mesma procedure usa outro insert para os itens, com id da venda.


create procedure inserir
@nome varchar(max),
@idade integer
as
insert into cliente(nome,idade) values(@nome,@idade)
select @@IDENTITY as 'ULTIMOID'
GOSTEI 0
Luiz Freitas

Luiz Freitas

16/09/2016

Olá!

Peluchi,

Como os outros usuários sugeriram, existem outras formas de fazer isso de dentro do Delphi mesmo, utilizando CachedUpdate por exemplo, mas eu não me lembro como faz, então vou sugerir uma solução que já utilizei e funcionou perfeitamente:

> Crie uma tabela para controle dos ID's, você pode controlar os ID's de todas as tabelas nas quais operações parecidas com essa (venda + item) precise ocorrer;
> No formulário de venda, ao iniciar uma nova venda você consulta a tabela de controle de ID's, pega o valor gravado nela, adiciona mais um (e já realiza o update na tabela de controle para que ele fique atualizada) e reserva esse valor;
> Os dados do cabeçalho da Venda, juntamente com o ID gerado, ficam gravados temporariamente em um ClientDataSet (CDS) ou em um FDMemTable (FMT), assim eles não são gravados diretamente no banco, ficam em memória até o processo ser concluído;
> Assim como no caso da Venda, insira os itens, utilizando como ID da Venda o valaor reservado anteriormente, também em um CDS ou em um FMT (para que eles fiquem em memória até o momento da gravação no banco);
> Caso a venda seja confirmada, transfira os dados para as tabelas de Vendas e de Itens no o banco de dados;
> Caso a venda seja interrompida por qualquer motivo simplesmente limpe o CDS ou FMT e estará tudo cancelado.

Em qualquer uma das situações, seja usando CachedUpdates, com um campo auto-incremento na própria tabela, ou usando a solução que sugeri, criando uma tabela para controlar os ID's, o ID que foi reservado para ser utilizado na venda iniciada (que pode se confirmar ou não) é perdido caso a operação não seja confirmada/concluída com sucesso.

Espero que você encontre uma solução que te atenda adequadamente.

Se quiser utilizar minha sugestão e tiver alguma dúvida é só perguntar.

Boa sorte!


Att,
Luiz
GOSTEI 0
POSTAR