Desvendando o SQL - Parte III - Alterando Registros
Autor: Rubens Lima | Publicado: 2013-07-21T17:22:00-03:00





Sejam bem vindos de volta,



Se estiverem lendo esse artigo estão acompanhando nossa série de artigos que vai tratar de alguns pontos da linguagem SQL. Nas primeiras duas partes dessa série começamos uma introdução sobre a linguagem, mostrando quais os comando básico, criamos um banco de dados, algumas tabelas e colocamos alguns registros nessas tabelas. Caso não tenham visto ainda os primeiros artigos é só acessar Desvendando o SQL - Parte I - Introdução e Desvendando o SQL - Parte II - Criando um Banco de Dados e Tabelas e conferir o que já foi explicado.


No último artigo criamos algumas tabelas e realizamos a carga das mesmas, de maneira simples mostramos como usar o create table e o insert. Nos scripts disponibilizados tinham muito mais informações e vamos explicar no seu devido tempo. Caso seja necessário, no final de cada artigo irei disponibilizar os scripts utilizados.




TEM QUE MUDAR TUDO, E AGORA?



Se por algum motivo esquecemos-nos de colocar um campo na tabela?&nbsp;
Ou algum atributo de um campo precisa ser alterado?&nbsp;
Ou tem campos demais?
Mas se tem campo novo ele precisa de carga não é?&nbsp;
Os valores preenchidos estão errados?
Tem registros que não deveriam está lá?





Se não sabe as respostas das perguntas acima, te digo que para todas existem respostas e de certo respostas simples, basta saber o que usar.

Alterando a estrutura da Tabela



Bem vamos supor que seus produtos agora tenham um número de série que precisa ser cadastrado, e é obrigatório, mas não existe um campo para isso, então vamos colocar. Um novo campo incluído vai sempre pro final da lista de campos, então se a ordem é importante tem que criar a tabela novamente com os campos certos, pois via script é inviável, pela ferramenta gráfica é possível, caso deseje eu ensino como.



Em uma nova consulta, digite o código abaixo, lembre-se de começar o script usando&nbsp;USE DBESTOQUE, para certeza que suas alterações estão em seu banco:



ALTER TABLE TBPRODUTO ADD NR_SERIE VARCHAR(15) NOT NULL



O comando ALTER TABLE tem como função fazer alterações na estrutura da tabela, como add ou retirar campos, atributos, contraints etc.



Com o comando estamos adicionando um campo por nome NR_SERIE do tipo cadeira de caracteres com até 15 posições com o atributo de obrigatoriedade, mas se é um número porque não colocar um inteiro? Lembra que os números de série às vezes contem letras? Então temos que considerar que dados serão inseridos no campo.



Pode rodar sua consulta, F5 e ver o que acontece. Pelo visto não deu certo não é? Apareceu uma mensagem parecida com abaixo?



Mensagem 4901, Nível 16, Estado 1, Linha 3

ALTER TABLE só permite a inclusão de colunas que contêm nulos ou uma definição DEFAULT especificada, ou a coluna que está sendo adicionada é uma coluna de identidade ou de carimbo de data/hora, ou, opcionalmente, se nenhuma das condições anteriores for atendida, a tabela deverá estar vazia para aceitar inclusão desta coluna. A coluna 'NR_SERIE' não pode ser adicionada a uma tabela 'TBPRODUTO' que não esteja vazia, porque ela não atende a essas condições.



Fiz de propósito, pela mensagem você irá perceber que não é possível incluir um campo obrigatório em linhas que já contem registros. Ao ser inserido um novo campo ele tem o valor Nulo, o que não é permitido pelo atributo NOT NULL, e agora? Agora tem que inserir o campo sem ser obrigatório.



ALTER TABLE TBPRODUTO ADD NR_SERIE VARCHAR(15) NULL



Agora executou sem erro, mas o campo não tem que ser obrigatório? Já resolvemos isso. Agora com a nova coluna inserida vamos colocar dados nela, para isso vamos usar o comando UPDATE, ele evita um monte de trabalho, ou então o jeito é ir de registro em registro e modificar.



Comentando um trecho de código



Abrindo um parêntese, em uma consulta SQL a execução roda tudo que estiver na tela, mas podemos querer executar somente uma parte da consulta, para isso existem algumas maneiras, uma delas é selecionar somente o texto a ser executado, o compilador considera somente o selecionado. Outra maneira é comentar o código a ser desconsiderado, deve ter visto isso no script do artigo anterior. Duas maneiras são as comuns de comentar, usando dois hífens para comentar uma linha ou usando a tag /* */



/* 

o que estiver aqui dentro está 

comentado e será desconsiderado 

*/



-- o que estiver nessa linha está comentado e será
desconsiderado



Claro que cada produto tem seu número de série, mas vamos automatizar esse preenchimento só para facilitar, em uma nova consulta ou na mesma insira o código abaixo.&nbsp;



UPDATE
TBPRODUTO

SET NR_SERIE = 'NS' + 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CAST(CD_PRODUTO AS VARCHAR(5)) + 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CAST(CD_REFERENCIA AS VARCHAR(10)) + 



&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CAST(CD_CATEGORIA AS VARCHAR(3)) FROM TBPRODUTO



O que fiz foi juntar alguns campos e criar um número de série pra cada produto, faça uma consulta na tabela de produto e verá os campos preenchidos.









Já explico o comando UPDATE, vamos resolver nosso problema do campo, pois ele deve ser obrigatório na é? Então vamos fazer o seguinte, mudar o atributo de obrigatoriedade do campo, para isso digite na consulta o seguinte:





ALTER TABLE TBPRODUTO ALTER COLUMN NR_SERIE VARCHAR(15) NOT NULL



Alteramos nossa coluna criada, agora ela é obrigatória como deveria. Viu como não é tão complicado como parece, completando, precisa apagar um campo? Então também é simples, somente lembre-se que se o campo for uma chave que esteja sendo utilizado por outra tabela não poderá excluí-lo antes de tirar a referencia dele na outra tabela, futuramente entrarei em detalhes sobre a normalização do banco. Então entenderá melhor. Agora faça outras alterações pra testar, mude alguns campos, crie outros, apague outros, deu errado? Roda os scripts do artigo anterior que o banco vai está perfeito de novo.



Alterando Registros



Mostramos um novo comando, o UPDATE, este comando serve para fazer alterações em registro de tabelas, ele a principio é bem simples, é só preciso dizer qual campo será alterado e que valor ele terá, caso não utilize nenhum condições, todos os campos das tabelas serão alterados, foi assim que aconteceu com o script acima. O atributo SET indica o inicio dos campos que serão alterados, para mais de um campo separe-os por vírgula, não e preciso repetir o SET como exemplo vamos alterar a quantidade de estoque e a data de inclusão de todo o estoque:



UPDATE
TBESTOQUE

SET 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; QTD_ESTOQUE
= QTD_ESTOQUE + 1,



&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DTH_MOVIMENTO
= GETDATE()



Incrementamos em 1(um) a quantidade de estoque e mudamos a data do movimento, o GETDATE() trás a data e horas atuais. Mas vixe, não era pra ter alterados todos os produtos, dois deles foram alterados com a quantidade errada, então agora vamos modificar somente os itens que queremos, para isso vamos incluir uma condição no UPDATE.



UPDATE
TBESTOQUE

SET 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; QTD_ESTOQUE
= QTD_ESTOQUE - 1

WHERE



&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CD_ESTOQUE
IN (4, 5)



Foi incluída uma clausula WHERE, após essa clausula incluímos as nossas consulta, você verá que quando estivermos fazendo consultas ela vai ser muito usada. Uma condição restringe uma alteração ou consulta, no nosso caso vamos dizer que somente serão alterados os registros de estoque onde os códigos são iguais a 4 ou 5, isso pela utilização do operador relacional IN, mostrado no primeiro artigo. Caso esses código sejam uma sequencia muito grande podemos utilizar o BETWEEN que nos dá um intervalo de valores como, por exemplo, BETWEEN 1 AND 10 incluindo as extremidades, ou seja, 1 e 10 entram.



É mais ou menos assim, atualize na tabela TBEstoque o campo QTD_ESTOQUE que vai ser igual a ele mesmo menos 1 onde o campo CD_ESTOQUE for igual a 4 ou 5.



Vale ressaltar que ao utilizar esse comando tenha o cuidado de colocar uma condição e que essa condição seja a correta, caso contrario, você poderá atualizar todos os registros da tabela, o que em determinadas situações pode ser um desastre.



Excluindo Registros



Bem agora na situação que é preciso excluir algum, ou alguns, registros das tabelas, e ai? Posso? Tudo vai depender da situação. É possível excluir tudo, mas...



Vamos supor que uma categoria foi cadastrada errada e precisamos excluí-la, a categoria “Massas” não vai mais existir, então pra que ficar lá não é? Simples é só digitar o comando abaixo, lembre-se de usar uma condição pra não acabar deletando a tabela toda.



DELETE FROM TBCATEGORIA WHERE CD_CATEGORIA = 4



Mas o que aconteceu? O sistema mostrou uma mensagem esquisita, e o que ela diz?



Mensagem 547, Nível 16, Estado 0, Linha 1

A instrução DELETE conflitou com a restrição do REFERENCE
"FK_PROD_CATG". O conflito ocorreu no banco de dados
"DBESTOQUE", tabela "dbo.TBProduto", column 'CD_CATEGORIA'.



A instrução foi finalizada.



Ela diz que o registro não pode ser excluído, pois isso vai causar um conflito na tabela de produtos devido à existência duma chave estrangeira. Isso é ruim? Sim e Não. Sim porque impede que nosso registro seja excluído, só que eu não quero mais ele lá. Não porque isso mostra que a existência de ligações entre as tabelas impede que o banco de dados vire uma bagunça, é a normalização funcionando de novo.



Ele problema pode ser resolvido de duas maneiras:



1º. Excluir na tabela de produtos todos os registros que estão ligados a essa categoria, mas isso implica em ter que excluir também os registros de estoque que constam os produtos, a chamada exclusão em cascata, mas a bagunça pode aumentar. Não recomendo no momento.



2º. Alterar os produtos que fazem referencia a essa categoria, colocando neles outra categoria, ai sim podemos excluir a categoria que queremos. Bem mais recomendado.



Então vamos optar no momento pela 2º solução, primeiro vamos incluir na tabela de categorias uma nova categoria como o nome de “Sem Categoria Definida”, utilize o script abaixo.



INSERT INTO TBCategoria (DESC_CATEGORIA) VALUES ('Sem Categoria Definida')



Feito isso vamos alterar na tabela de produtos os produtos que fazem referencia a categoria que vai ser excluída.



UPDATE&nbsp;TBPRODUTO

SET&nbsp;CD_CATEGORIA&nbsp;=&nbsp;(SELECT&nbsp;CD_CATEGORIA&nbsp;FROM&nbsp;TBCATEGORIA&nbsp;WHERE&nbsp;DESC_CATEGORIA&nbsp;=&nbsp;'Sem Categoria Definida')

WHERE&nbsp;CD_CATEGORIA&nbsp;=&nbsp;4



Agora pode excluir a categoria e nenhum problema ocorrerá.



DELETE&nbsp;FROM&nbsp;TBCATEGORIA&nbsp;WHERE&nbsp;CD_CATEGORIA&nbsp;=&nbsp;4



Viu como de um jeito ou de outro tem solução, bem vou terminar o artigo de hoje com um desafio. Com o que fizemos até agora é moleza.



Desafio



1º. Criar uma nova tabela de subcategoria, essa tabela deve ter 3 (três) campos, um de código, uma descrição e um que deve fazer referencia a tabela de categorias (chave estrangeira), todos obrigatórios, a chave primaria será o campo de código do tipo identity. Incluir uma descrição para a tabela;



2º. Fazer o script de carga dessa tabela;



3º. Altera a tabela de produtos, retirar o campo de categoria e incluir de subcategoria, esse campo fará referencia a nova tabela criada lembre-se de mudar a FK da tabela de produtos para o novo campo, será obrigatório e deve ser carregado com os códigos correto das subcategorias. Se achar necessário pode incluir novos produtos;



4º. Dica nos scripts disponibilizados no artigo anterior tem como excluir as Foreign Key;



Fácil demais não é, podem postar no comentário os scripts com as alterações, no próximo artigo vou incluir o script com a solução.



Por enquanto ficamos por aqui, caso deseje comentar, tirar dúvidas, deixar sugestões, fique a vontade e comente, se gostou fale, se não gostou fale também. Próximo artigo vamos começar nossas consultas usando o SELECT, espero por você. Até lá.



Abraço a todos



Scripts:

Comandos usados



Artigos anteriores:

Desvendando o SQL - Parte I - Introdução

Desvendando o SQL - Parte II - Criando um Banco de Dados e Tabelas