DML
Linguagem de Manipulação de Dados (ou DML, de Data Manipulation Language) é uma família de linguagens de computador utilizadas para a recuperação, inclusão, remoção e modificação de informações em bancos de dados. Pode ser procedural, que especifica como os dados devem ser obtidos do banco; pode também ser declarativa (não procedural), em que os usuários não necessitam especificar o caminho de acesso, isto é, como os dados serão obtidos. O padrão SQL é não procedural. DMLs foram utilizadas inicialmente apenas por programas de computador, porém (com o surgimento da SQL) também têm sido utilizadas por pessoas.
INSERT
É utilizado o comando INSERT para inserir linhas nas tabelas:
INSERT INTO clima VALUES ('São Francisco', 46, 50, 0.25, '1994-11-27');
Repare que todos os tipos de dado possuem formato de entrada de dados bastante óbvios. As constantes, que não são valores numéricos simples, geralmente devem estar entre apóstrofos ('), como no exemplo acima. O tipo date é, na verdade, muito flexível em relação aos dados que aceita, mas para este tutorial vamos nos fixar no formato sem ambigüidade mostrado acima.
O tipo point requer um par de coordenadas como entrada, como mostrado abaixo:
INSERT INTO cidades VALUES ('São Francisco', '(-194.0, 53.0)');
A sintaxe usada até agora requer que seja lembrada a ordem das colunas. Uma sintaxe alternativa permite declarar as colunas explicitamente:
INSERT INTO clima (cidade, temp_min, temp_max, prcp, data)
VALUES ('São Francisco', 43, 57, 0.0, '1994-11-29');
Se for desejado, pode-se declarar as colunas em uma ordem diferente, ou mesmo, omitir algumas colunas. Por exemplo, se a precipitação não for conhecida:
INSERT INTO clima (data, cidade, temp_max, temp_min)
VALUES ('1994-11-29', 'Hayward', 54, 37);
Muitos desenvolvedores consideram que declarar explicitamente as colunas é melhor que confiar na ordem implícita.
SELECT
Para trazer os dados de uma tabela, a tabela deve ser consultada. Para esta finalidade é utilizado o comando SELECT do SQL. Este comando é dividido em lista de seleção (a parte que especifica as colunas a serem trazidas), lista de tabelas (a parte que especifica as tabelas de onde os dados vão ser trazidos), e uma qualificação opcional (a parte onde são especificadas as restrições). Por exemplo, para trazer todas as linhas da tabela clima digite:
SELECT * FROM clima;
Aqui o * é uma forma abreviada de "todas as colunas". [1] Seriam obtidos os mesmos resultados usando:
SELECT cidade, temp_min, temp_max, prcp, data FROM clima;
A saída deve ser:
cidade | temp_min | temp_max | prcp | data ----------------+----------+----------+------+------------ São Francisco | 46 | 50 | 0.25 | 1994-11-27 São Francisco | 43 | 57 | 0 | 1994-11-29 Hayward | 37 | 54 | | 1994-11-29 (3 linhas)
Na lista de seleção podem ser especificadas expressões, e não apenas referências a colunas. Por exemplo, pode ser escrito
SELECT cidade, (temp_max+temp_min)/2 AS temp_media, data FROM clima;
cidade | temp_media | data ----------------+------------+------------ São Francisco | 48 | 1994-11-27 São Francisco | 50 | 1994-11-29 Hayward | 45 | 1994-11-29 (3 linhas)
Perceba que a cláusula AS foi utilizada para mudar o nome da coluna de saída (a cláusula AS é opcional).
A consulta pode ser "qualificada", adicionando a cláusula WHERE para especificar as linhas desejadas. A cláusula WHERE contém expressões booleanas (valor verdade), e somente são retornadas as linhas para as quais o resultado da expressão booleana for verdade. São permitidos os operadores booleanos usuais (AND, OR e NOT) na qualificação. Por exemplo, o comando abaixo mostra o clima de São Francisco nos dias de chuva:
SELECT * FROM clima WHERE cidade = 'São Francisco' AND prcp > 0.0;
Resultado:
cidade | temp_min | temp_max | prcp | data
----------------+----------+----------+------+------------
São Francisco | 46 | 50 | 0.25 | 1994-11-27
(1 linha)
Pode ser solicitado que os resultados da consulta sejam retornados em uma determinada ordem:
SELECT * FROM clima
ORDER BY cidade;
cidade | temp_min | temp_max | prcp | data
----------------+----------+----------+------+------------
Hayward | 37 | 54 | | 1994-11-29
São Francisco | 43 | 57 | 0 | 1994-11-29
São Francisco | 46 | 50 | 0.25 | 1994-11-27
Neste exemplo a ordem de classificação não está totalmente especificada e, portanto, as linhas de São Francisco podem retornar em qualquer ordem. Mas sempre seriam obtidos os resultados mostrados acima se fosse executado:
SELECT * FROM clima ORDER BY cidade, temp_min;
Pode ser solicitado que as linhas duplicadas sejam removidas do resultado da consulta:
SELECT DISTINCT cidade FROM clima; cidade --------------- Hayward São Francisco (2 linhas)
Novamente, neste exemplo a ordem das linhas pode variar. Pode-se garantir resultados consistentes utilizando DISTINCT e ORDER BY juntos:
SELECT DISTINCT cidade FROM clima ORDER BY cidade;
Até agora as consultas somente acessaram uma tabela de cada vez. As consultas podem acessar várias tabelas de uma vez, ou acessar a mesma tabela de uma maneira que várias linhas da tabela sejam processadas ao mesmo tempo. A consulta que acessa várias linhas da mesma tabela, ou de tabelas diferentes, de uma vez, é chamada de consulta de junção. Como exemplo, suponha que se queira listar todas as linhas de clima junto com a localização da cidade associada. Para fazer isto, é necessário comparar a coluna cidade de cada linha da tabela clima com a coluna nome de todas as linhas da tabela cidades, e selecionar os pares de linha onde estes valores são correspondentes.
Nota: Este é apenas um modelo conceitual, a junção geralmente é realizada de uma maneira mais eficiente que realmente comparar cada par de linhas possível, mas isto não é visível para o usuário.
Esta operação pode ser efetuada por meio da seguinte consulta:
SELECT *
FROM clima, cidades
WHERE cidade = nome;
cidade | temp_min | temp_max | prcp | data | nome | localizacao
----------------+----------+----------+------+------------+---------------+-------------
São Francisco | 46 | 50 | 0.25 | 1994-11-27 | São Francisco | (-194,53)
São Francisco | 43 | 57 | 0 | 1994-11-29 | São Francisco | (-194,53)
(2 linhas)
Duas coisas devem ser observadas no conjunto de resultados produzido:
Não existe nenhuma linha de resultado para a cidade Hayward. Isto acontece porque não existe entrada correspondente na tabela cidades para Hayward, e a junção ignora as linhas da tabela clima sem correspondência. Veremos em breve como isto pode ser corrigido.
Existem duas colunas contendo o nome da cidade, o que está correto porque a lista de colunas das tabelas clima e cidades estão concatenadas. Na prática isto não é desejado, sendo preferível, portanto, escrever a lista das colunas de saída explicitamente em vez de utilizar o *:
SELECT cidade, temp_min, temp_max, prcp, data, localizacao FROM clima, cidades WHERE cidade = nome;
UPDATE
As linhas existentes podem ser atualizadas utilizando o comando UPDATE. Suponha ter sido descoberto que as leituras de temperatura realizadas após 28 de novembro de 1994 estão todas 2 graus mais altas. Os dados podem ser atualizados da seguinte maneira:
UPDATE clima SET temp_max = temp_max - 2, temp_min = temp_min - 2 WHERE data > '1994-11-28';
Agora vejamos o novo estado dos dados:
SELECT * FROM clima;
cidade | temp_min | temp_max | prcp | data
----------------+----------+----------+------+------------
São Francisco | 46 | 50 | 0.25 | 1994-11-27
São Francisco | 41 | 55 | 0 | 1994-11-29
Hayward | 35 | 52 | | 1994-11-29
(3 linhas)
DELETE
As linhas podem ser excluídas da tabela através do comando DELETE. Suponha que não estamos mais interessados no clima de Hayward. Então podemos executar comando a seguir para excluir estas linhas da tabela
DELETE FROM clima WHERE cidade = 'Hayward';
e todos os registros de clima pertencentes a Hayward serão removidos. Agora vejamos o novo estado dos dados:
SELECT * FROM clima; cidade | temp_min | temp_max | prcp | data --------------+----------+----------+------+------------ São Francisco | 46 | 50 | 0.25 | 1994-11-27 São Francisco | 41 | 55 | 0 | 1994-11-29 (2 linhas)
Deve-se tomar cuidado com comandos na forma
DELETE FROM nome_da_tabela;
porque, sem uma qualificação, o comando DELETE remove todas as linhas da tabela, deixando-a vazia. O sistema não solicita confirmação antes de realizar esta operação.
OUTROS
Outros comandos utilizados.
INNER JOIN
Para se mostrar dados de mais de uma tabela, é necessário usar a instrução INNER JOIN, que adiciona tabelas para visualização utilizando a chave estrangeira.
SELECT nometab1, nometab2 FROM tab2 INNER JOIN tab1 ON (tab2.idtab = tab1.idtab);