SQL DML Básico (Manipulando Dados)

Inserindo Dados (INSERT)

Para inserir dados em uma tabela utilizamos o comando INSERT. A sintaxe do comando INSERT utiliza três blocos:

/* Definindo tabela */ 
INSERT INTO TABELA
/* Lista de campos separados por vírgula - se não for informada, serão todos os campos */
( CAMPO1, CAMPO2, CAMPO3, CAMPO4 ) 
/* Lista de valores a serem inseridos, separados por vírgula */
VALUES ('valor1', 2, '2006-12-31', NULL);

Textos devem estar entre apóstrofos ('). As datas no formato aaaa-mm-dd, também entre apóstrofos.

Valores NULL Os campos não informados receberão o valor nulo (NULL). Se o campo foi criado com a opção NOT NULL, isto acarretará um erro. Se possuir a opção valor padrão (DEFAULT), ao invés de NULL armazenará o valor DEFAULT especificado. Ainda, se o campo possuir uma TRIGGER de inserção vinculada, poderá ter um valor automaticamente calculado. Nos exemplos que utilizamos de criação de tabela, utilizamos um GENERATOR em conjunto com uma TRIGGER que cria um campo “autonumerado”, sempre que o valor inserido seja NULL. Campos definidos como PRIMARY KEY, por serem obrigatoriamente NOT NULL, evidentemente terão o mesmo tratamento.

Vejamos um exemplo considerando a tabela abaixo:

CREATE TABLE ALUNO (
MATRICULA CHAR(9) NOT NULL,
NOME VARCHAR(50),
DATANASC DATE,
DISCIPLINAS INTEGER
);

O código para inserir um registro pode ser algum dos abaixo, conforme a limitação de não inserir valores nulos para o campo MATRICULA:

/* Todos os campos, sem especificar */
INSERT INTO ALUNO 
VALUES ('200304521','MARIA DA SILVA','1978-09-05',3);
 
/* Todos os campos, especificados */
INSERT INTO ALUNO (MATRICULA, NOME, DATANASC, DISCIPLINAS)
VALUES ('200412453','JOÃO DA SILVA','1980-10-04', 5);
 
/* Omitindo a data de nascimento */
INSERT INTO ALUNO (MATRICULA, NOME, DISCIPLINAS)
VALUES ('200103345','SHEILA DA SILVA', 2);
 
/* As inserções a seguir geram erros */
 
INSERT INTO ALUNO 
VALUES ('200301248','FÁBIO DA SILVA','1976-08-18');
/* 
Count of read-write columns does not equal count of values
(Contagem de colunas não é igual à contagem de valores)
Existem menos campos ou valores que o necessário
*/
 
INSERT INTO ALUNO 
VALUES ('200501354','MAGDA DA SILVA','1976-13-18',4);
/*
conversion error from string "1976-13-18"
(erro de conversão da string "1976-13-18")
Data está errada, não pode ser convertida de texto em data (mês 13 não existe!)
*/
 
INSERT INTO ALUNO 
VALUES ('200501354','JOAQUIM JOSÉ DA SILVA XAVIER FILHO SOBRINHO NETO PARENTE DISTANTE','1976-12-18',4);
/*
arithmetic exception, numeric overflow, or string truncation
(excessão aritmética, sobrecarga numérica ou truncamento de string)
Algum valor extrapolou o limite de armazenamento - no caso, um nome com mais de 50 caracteres
*/

Quando se viola uma chave primária - informada em duplicidade - ou chave estrangeira - inserindo um valor que não é encontrado na tabela estrangeira - também se recebe mensagens de erro:

violation of PRIMARY or UNIQUE KEY constraint “INTEG_183” on table “TIPOCLIENTE”
(violação de restrição de CHAVE PRIMÁRIA ou ÚNICA “INTEG_183” na tabela “TIPOCLIENTE”)

violation of FOREIGN KEY constraint “INTEG_187” on table “CLIENTE”
(violação de restrição de CHAVE ESTRANGEIRA “INTEG_187” na tabela “CLIENTE”)

Selecionando Dados (SELECT)

Seleção é a operação mais utilizada em SQL. Veremos a seguir suas sintaxes mais básicas, criando gradativamente seleções mais complexas. O comando chave é o SELECT.

Sintaxe básica

/* Selecionar */
SELECT 
/* Lista de campos separados por vírgula */
CAMPO1, CAMPO2, CAMPO3
/* Da tabela */
FROM TABELA;

Para selecionar todos os campos, utilize o asterisco “*”.
A consulta abaixo seleciona todos registros:

SELECT * FROM TABELA;

É possível também informar o nome dos campos de forma completa, especificando o “TABELA.CAMPO”. Isto pode parecer redundante, mas com a junção de várias tabelas é necessário evitar a ambiqüidade, ou seja, fazer referência a campos que possuem o mesmo nome em duas tabelas de forma clara e específica.

SELECT TABELA.CAMPO1, TABELA.CAMPO2, TABELA.CAMPO3 FROM TABELA;

É possível, para facilitar, criar alias (apelidos) para tabelas e campos, facilitando sua referência. Tabelas ganham apelidos colocando-os logo em frente à tabela, e campos através da palavra chave AS (COMO). Campos calculados, concactenados são freqüentemente referenciados por alias.

SELECT 
A.MATRICULA, A.NOME AS NOMEALUNO 
FROM ALUNO A;
 
SELECT 
A.MATRICULA, A.NOME AS NOMEALUNO, C.CODCURSO
FROM ALUNO A, CURSO C
WHERE A.CODCURSO = C.CODCURSO;

Condições

A cláusula WHERE expressa a condição ONDE. É utilizada para:

  • Filtrar os registros dada uma ou mais restrições;
  • Relacionar tabelas.

Os campos que serão utilizados na filtragem não precisam ser exibidos no resultado da consulta.

A clásula WHERE é usada SEMPRE após a lista de tabelas.

Filtrando dados

Para filtrar dados, é necessário usar operadores ou comparadores. Os operadores básicos são:

Operador Descrição Exemplo
= igual a CAMPO1 = ‘RAFAEL’ – CAMPO1 = CAMPO5 – CAMPO1 = 5
<> diferente de CAMPO1 <> ‘RAFAEL’ – CAMPO1 <> CAMPO5 – CAMPO1 <> 5
> maior que CAMPO1 > CAMPO5 – CAMPO1 > 5
>= maior ou igual que CAMPO1 >= CAMPO5 – CAMPO1 >= 5
< menor que CAMPO1 < CAMPO5 – CAMPO1 < 5
=< menor ou igual que CAMPO1 =< CAMPO5 – CAMPO1 =< 5
LIKE como Usado em comparação de trechos de texto → CAMPO1 LIKE ’%RAFAEL%'
BETWEEN entre Entre dois valores → CAMPO1 BETWEEN 35 AND 50
IN em Contido numa lista de valores → CAMPO1 IN (1,2,3,4,5)

Observação: o símbolo percentual (%) é um coringa para pesquisas em texto, significa qualquer trecho de texto, inclusive nenhum.

Os campos utilizados no filtro podem, mas não precisam ser exibidos na seleção.

Exemplo:

/* Selecionar todos os campos */
SELECT *              
/* da tabela ALUNO*/
FROM ALUNO            
/* onde */
WHERE                 
/* o valor do campo DISCIPLINAS seja maior do que 3 */
DISCIPLINAS > 3;       
 
/* Selecionar todos os campos */
SELECT *              
/* da tabela ALUNO*/
FROM ALUNO            
/* onde */
WHERE                 
/* o valor do campo NOME comece com 'RAFAEL' e continue com qualquer coisa (inclusive nada) */
NOME LIKE 'RAFAEL%';

Para filtrar por mais de um campo, utilize as operadores lógicas:

Operador Descrição
OR OU Um filtro ou outro
AND E Um filtro e outro filtro
/* Selecionar todos os campos */
SELECT *              
/* da tabela ALUNO*/
FROM ALUNO            
/* onde */
WHERE                 
/* o valor do campo DISCIPLINAS seja maior do que 3 */
DISCIPLINAS > 3       
/* E o valor do campo DATANASC seja maior do que 01/01/1980 */
AND DATANASC > '1980-01-01';
 
 
/* Selecionar todos os campos */
SELECT *              
/* da tabela ALUNO*/
FROM ALUNO            
/* onde */
WHERE                 
/* o valor do campo DISCIPLINAS seja maior do que 3 */
DISCIPLINAS > 3       
/* E o valor do campo DATANASC seja maior do que 01/01/1980 */
AND DATANASC > '1980-01-01';
 
 
/* Selecionar todos os campos */
SELECT *              
/* da tabela ALUNO*/
FROM ALUNO            
/* onde */
WHERE                 
/* o valor do campo MATRICULA seja igual a 200401542 */
MATRICULA = '200401542'       
/* OU o valor do campo MATRICULA seja igual a 200306482*/
OR MATRICULA = '200306482';

O uso de parenteses pode modificar a ordem de avaliação; os parenteses tem prioridade sobre o operador, assim como as expressões aritméticas.

Relacionando Tabelas

Relacionar tabelas é uma forma muito importante de cruzamento de dados, e também a mais simples. A forma de fazer isto é a seguinte:

  1. Identifique a relação entre campo CHAVE ESTRANGEIRA e compare com o campo que é CHAVE PRIMÁRIA da TABELA ESTRANGEIRA (*);
  2. Crie uma condição relacionando os campos das duas tabelas, com o operador “igual”;
  3. Repita para cada relacionamento da tabela.

Este trabalho se torna mais minucioso quando existem várias tabelas relacionadas.

Considerando as tabelas:

CREATE TABLE CURSO (
CODCURSO CHAR(3) NOT NULL,
DESCRICAO VARCHAR(50),
PRIMARY KEY (CODCURSO)
);
 
CREATE TABLE TURMA (
CODTURMA CHAR(3) NOT NULL,
DESCRICAO VARCHAR(20),
PRIMARY KEY (CODTURMA)
);
 
CREATE TABLE ALUNO (
MATRICULA CHAR(9) NOT NULL,
NOME VARCHAR(50),
DATANASC DATE,
DISCIPLINAS INTEGER,
CODCURSO CHAR(3),
CODTURMA CHAR(3),
PRIMARY KEY (MATRICULA),
FOREIGN KEY (CODCURSO) REFERENCES CURSO (CODCURSO),
FOREIGN KEY (CODTURMA) REFERENCES TURMA (CODTURMA)
);

Uma consulta para verificar o aluno com seu curso e turma seria:

/* Selecionar campos MATRICULA, NOME, DESCRICAO do Curso e DESCRICAO Turma */
SELECT ALUNO.MATRICULA, ALUNO.NOME, CURSO.DESCRICAO, TURMA.DESCRICAO
/* das tabelas*/
FROM ALUNO, CURSO, TURMA
/* onde */
WHERE
/* vincula ALUNO a CURSO */
ALUNO.CODCURSO = CURSO.CODCURSO
/* E vincula ALUNO a TURMA */
AND ALUNO.CODTURMA = TURMA.CODTURMA;

Perceba que foi necessário especificar os campos DESCRICAO, CODTURMA, CODCURSO, pois aparecem mais de uma vez no resultado - existem em mais de uma tabela.

Ordenação (ORDER BY)

A cláusula ORDER BY permite ordenar o resultado por campos das tabelas envolvidas. Sua sintaxe é simples, e é SEMPRE APÓS o final das condições da cláusula WHERE, se ela existir - ou após onde ela estaria.

Pode-se informar mais de um campo; desta forma, será ordenado primeiramente pelo primeiro da lista, em seguida por cada um dos demais.

É possível determinar a forma de ordenação:

  • ASC, ascendente, que é o padrão caso não seja informada, exibe os registros em ordem alfabética, numericamente crescente ou datas mais antigas primeiro, conforme o tipo do campo.;
  • DESC, descendente, exibe os registros em ordem alfabética inversa, numericamente decrescente ou datas mais novas primeiro, conforme o tipo do campo.
SELECT ALUNO.MATRICULA, ALUNO.NOME, CURSO.DESCRICAO, TURMA.DESCRICAO
FROM ALUNO, CURSO, TURMA
WHERE
ALUNO.CODCURSO = CURSO.CODCURSO
AND ALUNO.CODTURMA = TURMA.CODTURMA
/* Ordenando pelo curso, depois pela turma, depois em ordem alfabética o nome dos alunos*/
ORDER BY CURSO.CODCURSO, TURMA.CODTURMA, ALUNO.NOME;
 
SELECT
*
FROM ALUNOS
/* Ordenando por alunos mais novos*/
ORDER BY DATANASC DESC;

Campos calculados, concatenação e funções

O FIREBIRD permite a execução de algumas operações entre

O Firebird possui um conjunto reduzido de funções

Agrupamento (GROUP e HAVING)

Atualizando Dados (UPDATE)

Para atualizar dados em uma tabela utilizamos o comando UPDATE. A palavra chave SET (definir) define os campos a serem alterados. A sintaxe do comando UPDATE é quase sempre utilizada em conjunto com a cláusula WHERE, restringindo os registros a serem atualizados. Isto nos gera 3 sintaxes básicas:

  • Alterando TODOS OS REGISTROS - sem cláusula WHERE:
/* Definindo tabela */ 
UPDATE TABELA
/* Lista de campos a serem atualizados separados por vírgula */
SET
  CAMPO1 = 'Novo Valor',
  CAMPO2 = 45,
  CAMPO3 = '2006-12-31';
  • Alterando APENAS UM REGISTRO ESPECÍFICO - cláusula WHERE filtrando a chave primária da tabela:
/* Definindo tabela */ 
UPDATE TABELA
/* Lista de campos a serem atualizados separados por vírgula */
SET
  CAMPO1 = 'Novo Valor',
  CAMPO2 = 45,
  CAMPO3 = '2006-12-31'
/* Filtrando a chave primária */
WHERE
    CAMPO_QUE_É_CHAVE_PRIMÁRIA = 4587
  • Alterando VÁRIOS REGISTROS - cláusula WHERE filtrando um ou mais registros da tabela:
/* Definindo tabela */ 
UPDATE TABELA
/* Lista de campos a serem atualizados separados por vírgula */
SET
  CAMPO1 = 'Novo Valor',
  CAMPO2 = 45,
  CAMPO3 = '2006-12-31'
/* Filtrando vários registros */
WHERE
    CAMPO1 = 'Valor qualquer'
AND CAMPO2 > 2;

Um cuidado muito grande é necessário quando atualiza-se vários registros simultaneamente, para evitar que o UPDATE gere atualizações em mais registros que o desejado. Uma prática inteligente é realizar um SELECT com o mesmo filtro (clásula WHERE) antes, testando se a atualização será realizada nos registros corretos. Exemplo:

/* Primeiro selecionamos os registros e conferimos o filtro */ 
SELECT * FROM TABELA
WHERE
    CAMPO1 = 'Valor qualquer'
AND CAMPO2 > 2;
 
/* Se os registros estiverem corretos, então realiza-se a atualização */ 
UPDATE TABELA
SET
  CAMPO1 = 'Novo Valor',
  CAMPO2 = 45,
  CAMPO3 = '2006-12-31'
WHERE
    CAMPO1 = 'Valor qualquer'
AND CAMPO2 > 2;

Outra forma é lembrar que as alterações só serão confirmadas após um COMMIT. Então, é possível selecionar os dados após a atualização, checá-los e apenas depois realizar o COMMIT.

Assim como o comando INSERT, o UPDATE gerará erros se o valor atualizado não respeitar o tipo/tamanho do campo, chaves estrangeiras ou tiver erros de sintaxe.

Vejamos um exemplo considerando a tabela abaixo:

CREATE TABLE ALUNO (
MATRICULA CHAR(9) NOT NULL,
NOME VARCHAR(50),
DATANASC DATE,
DISCIPLINAS INTEGER,
PRIMARY KEY (MATRICULA)
);

Nos exemplos abaixo considera-se que existam alguns registros na tabela.

  • Alterando TODOS OS REGISTROS - sem cláusula WHERE:
/* Definindo tabela */ 
UPDATE ALUNO
/* Lista de campos a serem atualizados separados por vírgula 
   Atualizando o campo DISPLINAS para 5
*/
SET
  DISCIPLINAS = 5;
  • Alterando APENAS UM REGISTRO ESPECÍFICO - cláusula WHERE filtrando a chave primária da tabela:
/* Definindo tabela */ 
UPDATE ALUNO
/* Lista de campos a serem atualizados separados por vírgula 
   Atualizando o campo DISPLINAS para 5
*/
SET
  DISCIPLINAS = 5
/* Filtrando apenas um registro através da chave primária MATRICULA */
WHERE
    MATRICULA = 217
  • Alterando VÁRIOS REGISTROS - cláusula WHERE filtrando um ou mais registros da tabela:
/* Definindo tabela */ 
UPDATE ALUNO
/* Lista de campos a serem atualizados separados por vírgula 
   Atualizando o campo DISPLINAS para 5
*/
SET
  DISCIPLINAS = 5
/* Filtrando vários registros */
WHERE
    MATRICULA > 45
AND DATANASC > '1980-01-01'

Excluindo Dados (DELETE)

Para atualizar dados em uma tabela utilizamos o comando DELETE. A sintaxe do comando DELETE é quase sempre utilizada em conjunto com a cláusula WHERE, restringindo os registros a serem atualizados. Funciona como um SELECT que apaga os registros selecionados. Isto nos gera 3 sintaxes básicas, como no UPDATE:

  • Excluindo TODOS OS REGISTROS - sem cláusula WHERE:
/* Definindo tabela */ 
DELETE FROM TABELA;
  • Excluindo APENAS UM REGISTRO ESPECÍFICO - cláusula WHERE filtrando a chave primária da tabela:
/* Definindo tabela */ 
DELETE FROM TABELA
/* Filtrando a chave primária */
WHERE
    CAMPO_QUE_É_CHAVE_PRIMÁRIA = 4587
  • Filtrando VÁRIOS REGISTROS - cláusula WHERE filtrando um ou mais registros da tabela:
/* Definindo tabela */ 
DELETE FROM TABELA
/* Filtrando vários registros */
WHERE
    CAMPO1 = 'Valor qualquer'
AND CAMPO2 > 2;

Um cuidado muito grande é necessário quando exclui-se vários registros simultaneamente, para evitar que o DELETE exclua mais registros que o desejado desejado. Uma prática inteligente é realizar um SELECT com o mesmo filtro (clásula WHERE) antes, testando se a exclusão será realizada nos registros corretos (mesma dica usada para o UPDATE. Exemplo:

/* Primeiro selecionamos os registros e conferimos o filtro */ 
SELECT * FROM TABELA
WHERE
    CAMPO1 = 'Valor qualquer'
AND CAMPO2 > 2;
 
/* Se os registros estiverem corretos, então realiza-se a atualização */ 
DELETE FROM TABELA
WHERE
    CAMPO1 = 'Valor qualquer'
AND CAMPO2 > 2;

Outra forma é lembrar que as alterações só serão confirmadas após um COMMIT. Então, é possível selecionar os dados após a atualização, checá-los e apenas depois realizar o COMMIT.

O comando DELETE gerará erros se o valor atualizado não respeitar o tipo/tamanho do campo, chaves estrangeiras ou tiver erros de sintaxe. Em especial, apagar registros de tabelas que são tabelas estrangeiras de outras podem gerar erros de violação de chave estrangeira - (violation of FOREIGN KEY).

Vejamos um exemplo considerando a tabela abaixo:

CREATE TABLE ALUNO (
MATRICULA CHAR(9) NOT NULL,
NOME VARCHAR(50),
DATANASC DATE,
ISCIPLINAS INTEGER,
CODCURSO CHAR(3),
CODTURMA CHAR(3),
PRIMARY KEY (MATRICULA)
);

Nos exemplos abaixo considera-se que existam alguns registros na tabela.

  • Excluindo TODOS OS REGISTROS - sem cláusula WHERE:
/* Definindo tabela */ 
DELETE FROM ALUNO;
  • Excluindo APENAS UM REGISTRO ESPECÍFICO - cláusula WHERE filtrando a chave primária da tabela:
/* Definindo tabela */ 
DELETE FROM ALUNO
/* Filtrando apenas um registro através da chave primária MATRICULA */
WHERE
    MATRICULA = 217
  • Excluindo VÁRIOS REGISTROS - cláusula WHERE filtrando um ou mais registros da tabela:
/* Definindo tabela */ 
DELETE FROM ALUNO
/* Filtrando vários registros */
WHERE
    MATRICULA > 45
AND DATANASC > '1980-01-01'