INSERT com SELECT
Por Luiz Paulo de Oliveira Santos
Data de Publicação: 17 de Setembro de 2006
Uma possibilidade interessante e desconhecida de muitos desenvolvedores que utilizam SQL é o uso de duas instruções SQL em uma única chamada. Por exemplo: A instrução INSERT que é responsável por inserir registros em tabelas, e, pode ser utilizada em conjunto com outras instruções, como o SELECT, por exemplo.
A instrução SELECT do SQL é além de polêmica bastante complexa. Com ela podemos extrair informações dos mais diversos tipos, ou seja, podemos utilizar o SELECT para obter desde resultados de cálculos básicos até buscas complexas e mais elaboradas, como nos exemplos a seguir:
SELECT 1+1
ou
(SELECT * FROM `xoops_users` where (uid >1) and (uid < 5))
UNION
(SELECT * FROM `xoops_users` where (uid >10) and (uid < 15)) ORDER BY uname;
Podemos utilizar o SELECT para extrair informações e canalizar o resultado obtido para outra instrução SQL. É o proposto no título do artigo, e o que será demonstrado a seguir.
Em uma situação onde existe a necessidade de gerar uma tabela de dados para ser trabalhada, e, ao final dos trabalhos ser exportada para outro sistema, por exemplo. Necessita-se importar dados de diferentes tabelas ou intervalos da tabela e colocar tudo em uma única tabela (tabela resposta). Logo teremos que inserir registros na tabela que armazenará a resposta.
A inserção dos dados é efetuada com a instrução INSERT, que é bastante simples. Basicamente informa-se a tabela que receberá os dados, os campos que serão preenchidos (e podem ser omitidos caso todos os campos sejam preenchidos) e a massa de dados que preencherá os campos, conforme o exemplo:
INSERT INTO <tabela> (lista de campos,...)
VALUES (massa de dados);
Sendo que a massa de dados deve obedecer a lista de campos informada.
Supondo que exista a tabela respostas com a seguinte estrutura:
| Campo | Tipo |
| IDENVIO | INT(11) |
| NOME | VARCHAR(50) |
| IDDESTINO | INT(11) |
Para inserirmos um registro na tabela respostas a instrução INSERT terá a seguinte sintaxe:
INSERT INTO respostas (IDENVIO, NOME, IDDESTINO) VALUES (11,"lpaulo",132);
Para efetuarmos a importação devida, deve-se obter os campos IDENVIO e NOME da tabela xoops_users (nos campos uid e uname respectivamente) e o campo IDDESTINO da tabela xoops_xoopscomments (campo com_id). Logo, necessitam-se buscar dados em duas tabelas e armazenar a resposta na tabela respostas. Para buscar os dados nas tabelas utilizaremos um SELECT. Porém deve-se filtrar os registros da tabela xoops_xoopscomments, de forma que para cada registro de xoops_users seja exibido com seu equivalente em xoops_xoopscomments.
A seguir temos a instrução que faz a extração dos dados:
SELECT xoops_users.uid, xoops_users.uname,
xoops_xoopscomments.com_id
FROM xoops_users, xoops_xoopscomments
WHERE xoops_users.uid = xoops_xoopscomments.com_uid
No SELECT acima obtemos 3 campos, sendo dois deles INTEGER e um VARCHAR.
Agora será unido o SELECT ao INSERT:
INSERT INTO `respostas` (IDENVIO, NOME, IDDESTINO)
SELECT xoops_users.uid, xoops_users.uname,
xoops_xoopscomments.com_id
FROM xoops_users, xoops_xoopscomments
WHERE xoops_users.uid = xoops_xoopscomments.com_uid
Desta forma será inserido na tabela respostas os registros obtidos na consulta com SELECT. Observe que a clausula VALUES foi omitida. Em alguns casos a clausula VALUES pode ser omitida e em outros casos não. Em uma próxima oportunidade o assunto será estudado.
E as variações e aplicações para esse tipo de sintaxe são simplesmente ilimitadas! O limite é a necessidade e criatividade de cada um.
Nota: O uso do INSERT em conjunto com SELECT é muito útil, porém deve-se lembrar sempre das formas normais que foram empregadas para normalização do banco de dados. Se as formas normais não forem respeitadas, redundâncias podem aparecer em seu banco! Mas formas normais é assunto para outro bate papo.
Espero que essa pequena dica seja útil quando precisar "importar" dados provenientes de tabelas que já existam.
Um forte abraço e até mais!
Veja a relação completa dos artigos da Bancos de Dados Livres
Para se manter atualizado sobre as novidades desta coluna, consulte sempre o newsfeed RSS
Para saber mais sobre RSS, leia o artigo O Padrão RSS - A luz no fim do túnel.
Opinião dos Leitores
12 Dez 2011, 15:33
Utilizei em uma aplicação no phpMyAdmin em que não estava funcionando pois eu não havia omitido o campo Values...
Valew'Ss Pela dica!
Gostei tanto que para te agradecer, eu cliquei no seu AdSense rs
Se todo mundo fizece isso você ficaria rica logo rs
E já está salvo em minha biblioteca rs
13 Jul 2011, 16:19
preciso salvar os dados do registro porém está dando erro quando eu uso depois do Value a propriedade da Caixa de Texto para atualizar de acordo com o dado que o usuario digit no formulario. Olha a sintaxe q to usando:
.CommandText = "INSERT INTO Usuarios (CodUsuario, NomeUsuario, Endereco, Cidade, Estado, CEP, Telefone) VALUES (&txtCodUsuario.text,'Louis Pasteurs Bisteca','Rua Dom Pedro I, 45 - Mariana','Jaú', 'SP','13210-270','11-4566-1222');"
05 Ago 2010, 13:27
Fiz a seguinte query, mas não funcionou o que poderi a ser?
Insert test.coletor (codColetorId -'17', car_numeroID, enviado, codTipoLibercao)
Select test.coletor where codcoletorID = '15'
10 Jul 2009, 22:23
SELECT artigo, cart, ccolec, cdep,centr, chave,colecao, tecido, cor, cor1,cor2,cor3, cor4,cor5,cor6,cor7,cor8,depto,entrega,foto,pedido,preco_cust, preco_loja, produto,razao, refinter, status, statuscor, verba, verba1, verba2, verba3, verba4, verba5, verba6, verba7, verba8, entrega, entrega1, entrega2, entrega3, entrega4, entrega5, entrega6, entrega7, entrega8
FROM auxsort
ORDER BY chave,produto
POR QUE ESTA DANDO ERRO?
28 Mar 2008, 18:03
Tô com uma dúvida. Ao utilizar um select, a instrução sql me retornará um registro da tabela caso encontre e null caso não encontre na tabela, não é isso mesmo? Pois bem, gostaria de saber como faço pra buscar ou capturar, por ex., somente o nome do cliente (string) ao invés do registro todo da tabela? Estou fazendo uma página em .net, utilizando c# e o banco de dados postgre. Se alguém puder me ajudar. Obrigado
18 Set 2006, 17:02
18 Set 2006, 15:46
18 Set 2006, 15:46
> valorers que já não existam ??
> Sobre o texto , muito bom :)
insert into
destino (nro, nome)
select
nro, nome
from
origem
where
nro not in (select nro from destino);
No PostgreSQL vai fácil. =)
18 Set 2006, 15:44
18 Set 2006, 15:33
Um abraço e parabéns Luiz Paulo
(Notaram quantos LUIZES nessa página? :D)
18 Set 2006, 14:52
INSERT B (ID, NOME)
SELECT A.ID, A.NOME
FROM Tabela_A A
LEFT OUTER JOIN Tabela_B B
ON A.ID = B.ID
WHERE B.ID IS NULL
18 Set 2006, 14:20
Sobre o texto , muito bom :)
18 Set 2006, 13:55
Luiz Gonzaga, quando você utiliza insert e select na mesma instrução, o VALUES não é utilizado.
18 Set 2006, 13:43


