Samuel Corradi

Blog

Inserindo registros dependentes entre sí no MySQL

samuel corradi, programacao, metodologia, desenvolvimento

O objetivo desse texto é ensinar como buscar o maior resultado possível de uma coluna utilizando o SGBD MySQL (provavelmente o comando é o mesmo para outros SGBDs). E também como se utilizar desse comando para incluir em uma tabela registros que dependem de dados de outra tabela, que estão sendo inseridos ao mesmo tempo, na mesma operação de inclusão. Utilizei como exemplo ilustrativo o problema em inserir um produto e sua imagem em um programa de cadastro de produtos. Vamos lá:

As vezes queremos saber qual o valor máximo para uma coluna usando o MySQL. Isso é útil nos casos em que queremos, por exemplo, localizar o último registro inserido em uma tabela.

Para fazer isso, utilize a função MAX() do MySQL.

SELECT MAX(id) AS codProduto FROM produtos;

Se quiser o valor mínimo, utilize MIN().

Lembrando que essas funções funcionam melhor com campos numéricos.

Estudo de caso

Imagine que você está desenvolvendo um cadastro de produtos, e que esse cadastro inclui também uma imagem do produto. Então teremos uma tabela para os dados do produto, e outra tabela para armazenar o caminho da imagem de cada produto no servidor de imagens.

A tabela produtos teria um campo chamado 'ID' como PK (Primary Key - Chave Primária) e a tabela IMAGENS deverá ter um campo chamado 'CODPRODUTO' como FK (Foreing Key - Chave Extrangeira) fazendo a ligação entre o produto e sua imagem.

Problema

Mas como podemos fazer essa ligação entre um e outro se ainda não inserimos o produto e, por tanto, não temos sua chave PK para utilizar como FK na tabela das imagens?

Solução

Me ocorreram 3 soluções para isso:

A primeira, e mais simples, é dividir a aplicação em 2 telas. Uma para inserir os produtos, e outra para inserir as imagens dos produtos. Dessa forma, ao inserir a imagem para um produto, o produto já deverá estar inserido e teremos como utilizar sua PK.

A segunda, e mais complexa, seria permanecer utilizando numa mesma tela tanto o cadastro do produto quanto da imagem (o que acho mais elegante), e utilizar uma Stored Procedure para inserir o produto e retornar para sua aplicação o 'ID' do produto inserido, para então fazer o insert da imagem usando o ID retornado como FK.

A terceira, e que utilizei recentemente, é utilizar a mesma tela para o cadastro do produto e da imagem, e após dar o insert do produto, fazer um select buscando o ID do último produto inserido e utilizar o resultado como FK para inserir a imagem.

Ou seja, a inserção do produto no sistema teve que acontecer em três etapas:

-- 1. inserimos o produto
INSERT INTO produtos (id, nome, categoria) VALUES (02, Produto1, Carros);

-- 2. pegamos o id do produto inserido
SELECT MAX(id) AS codProduto FROM produtos;

-- 3. inserimos a imagem do produto utilizando o ID do produdo
INSERT INTO imagensProdutos (id, codProduto, arquivo) VALUES (01, 02, produto02.jpg);

Reconheço que, na maioria das vezes, a utilização de Storage Procedures é a melhor solução. Pois reduz a quantidade de I/O em disco, quantidade de tráfego na rede, e utiliza da otimização do próprio banco de dados para fazer a operação. Porém nesse caso, a terceira opção resolveu muito bem meu problema.

Observação

Se sua chave primária possuir o atributo ZEROFILL, o comando MAX() irá retornar o campo sem os zeros a esquerda. Por tanto, se suas PKs forem 001, 002 e 003. Max irá retornar 3 como resultado.
Caso queria, por qualquer motivo, retornar o valor com seus zeros a esquerda, a solução que encontrei foi utilizar o comando com uma subconsulta:

SELECT id AS codProduto FROM produtos WHERE id=(SELECT MAX(id) FROM produtos);

Incluir comentário






1 mensagens enviadas

Ricardo

BOA!

Procurei essa função (max()) e só achei aqui!

valeu!!!

Últimos posts:

Destaques:

PHP Coupé - Desenvolvimento rápido e reaproveitável vForm - Validador universal de formulários

Programming and design by Samuel Corradi