SQL - Definição
– Sigla para Structured Query Language (ou Linguagem de Consulta Estruturada).
– SQL é basicamente a linguagem padrão para manipulação de bancos de dados relacionais. Por meio dela, um usuário pode executar comandos para inserir, pesquisar, atualizar ou deletar registros em um banco de dados, criar ou excluir tabelas, conceder ou revogar permissões para acessar o banco de dados, entre diversos outros recursos.
– Essa linguagem permite:
– SQL é uma linguagem declarativa.
– Com o passar do tempo, alguns fornecedores introduziram alguns comandos procedurais e algumas **extensões à linguagem SQL e lançaram com nomes parecidos, tais como: PL/SQL ou Transact-SQL. No entanto, essas extensões são conhecidas como dialetos SQL **e, não, SQL em sua forma original!
Linguagens - Paradigma declarativo x Paradigma procedural
—- Você declara o resultado que deseja obter, e o sistema (neste caso, o banco de dados)** se encarrega de decidir como chegar lá**.
– Uma linguagem declarativa descreve o que fazer;
– a linguagem declarativa não está nem aí para como será feito, ela só quer o resultado.
– A linguagem SQL se trata de uma linguagem declarativa.
– Não precisa dizer:
📌 Isso é responsabilidade do otimizador de consultas do SGBD (Sistema Gerenciador de Banco de Dados).
– Você precisa especificar passo a passo o procedimento a ser executado.
– uma linguagem procedural descreve como fazer.
– a linguagem
procedural passo a passo** como algo deve ser feito**
– Você precisa dizer como:
=> Comparativo:
– SQL (declarativa) é ideal quando você consulta dados em bancos relacionais — é mais enxuta, eficiente e otimizada para esse tipo de tarefa.
– Procedural é usada quando você precisa de controle total sobre a lógica do processo, como criar algoritmos, processar dados em memória, criar laços e condições complexas etc.
Tipos de dados pré-definidos pela linguagem SQL
– É importante estudar os** tipos de dados pré-definidos pela linguagem SQL**.
– Em uma tabela armazenada em um banco de dados relacional, temos linhas e colunas. Para que uma tabela seja criada, é necessário especificar qual tipo de dados serão armazenados em suas colunas.
– O Padrão ANSI/SQL traz um conjunto de tipos de dados básicos padronizados pela linguagem.
1) Textuais
– Também conhecido como literal, esse tipo de dado é basicamente uma cadeia de caracteres.
– Podem ter um tamanho fixo (Ex: CHAR(n), em que n é o número fixo de caracteres) ou um tamanho variável (Ex: VARCHAR(n), em que **n **é o número máximo de caracteres).
– A modelagem com CHAR(n) obriga o usuário a escrever um texto com exatamente 280 caracteres (nem mais, nem menos).
– O Padrão ANSI/SQL-99 trouxe ainda um tipo de texto chamado CLOB (Character Large Object) capaz de armazenar textos gigantescos, sendo que o tamanho máximo depende da especificidade de cada SGBD.
– Por fim, é interessante lembrar que – **ao inserir um texto diretamente **no banco de dados – ele deve ser colocado entre aspas simples (apóstrofos).
– Ademais, ele é Case Sensitive (diferencia maiúsculas de minúsculas).
– Observação importante: os valores do tipo texto inseridos em uma linha do banco de dados são Case Sensitive, mas as palavras-chave que compõem a linguagem, não. Dessa forma, você pode escrever tanto CREATE TABLE quanto create table.
2) Numérico
– Esse tipo de dado inclui números inteiros de diversos tamanhos (Ex: INTEGER, INT ou SMALLINT) e números reais (FLOAT, REAL e DOUBLE PRECISION) – também conhecidos como ponto flutuante.
3) Binário
– Esse tipo de dado é basicamente uma cadeia de bits. Podem ter um tamanho fixo (Ex: BIT(n), em que **n **é o número fixo de caracteres) ou um tamanho variável (Ex: BIT VARYING(n), em que n é o número máximo de caracteres).
– Há ainda o BLOB (Binary Large Object), capaz de armazenar uma quantidade gigantesca de bits.
-** Um arquivo é basicamente um conjunto de bits** (seja ele uma foto, um documento, um software, um vídeo, entre outros).
4) Booleano
– Esse tipo de dado tem como valores tradicionais **TRUE **(Verdadeiro) ou FALSE (Falso).
– O tipo Booleano utiliza** apenas 1 byte para seu armazenamento, uma vez que o valor falso é representado por 0** (00000000) e o valor verdadeiro é representado por **1 **(00000001).
=> Expressões lógicas
– Em expressões lógicas AND, OR e NOT, o **valor booleano TRUE **representa uma condição verdadeira e o **valor booleano FALSE **representa uma condição falsa.
=> Terceiro valor: NULL
– Vimos os valores booleanos tradicionais (TRUE e FALSE), no entanto o SQL trabalha com a Lógica de Três Valores.
– Além dos dois valores tradicionais, temos um terceiro valor: NULL. Esse valor é utilizado para representar um valor que está faltando, mas que – em geral – pode ter três interpretações diferentes.
– Normalmente, não é possível determinar
qual dos significados é intencionado; por exemplo, um NULL para o telefone residencial de uma pessoa pode ter qualquer um dos três significados.
– Logo, a SQL não distingue entre os diferentes significados de NULL.
– Em geral, cada valor NULL individual é considerado diferente de qualquer outro valor NULL nos diversos registros do banco de dados.
– Quando um NULL está envolvido em uma operação de comparação, o resultado é UNKNOWN.
– UNKNOWN é um valor desconhecido que pode ser **TRUE **ou FALSE.
– Assim, a** SQL** usa uma lógica de três valores com os valores TRUE, FALSE e UNKNOWN em vez da lógica de dois valores (booleana) padrão, com os valores TRUE e FALSE.
– Portanto, é necessário definir os resultados (ou valores verdadeiros) das expressões lógicas de três valores quando os conectivos lógicos AND, OR e NOT forem usados.
– O banco de dados **trata os valores desconhecidos **para garantir a precisão dos resultados.
5) Data
– Esse tipo de dado possui dez posições, e seus componentes são DAY (Dia), MONTH (Mês) e YEAR (Ano) na forma DD-MM-YYYY (Ex: 30/03/2019).
– Somente datas válidas devem ser permitidas pela implementação do SQL. Em outras palavras, os meses devem estar entre 1 e 12 e os dias devem estar entre 1 e 31.
– Além disso, os dias devem ser válidos para o mês correspondente – logo, não é possível haver a data 30/02/2020 porque o mês de fevereiro nunca tem 30 dias.
6) Hora
– Esse tipo de dado possui pelo menos oito posições compostas por HOUR (Hora), MINUTE (Minuto) e SECOND (Segundo) na forma HH:MM:SS.
– Somente horas válidas devem ser permitidas pela implementação do SQL. Em outras palavras, as horas devem estar entre 0 e 23, os **minutos devem estar entre 0 e 59 **e os segundos também devem estar entre 0 e 59.
7) Outros
– Existem outros tipos de dados que foram acrescentados em versões posteriores do Padrão ANSI/SQL.
– Outro tipo interessante é o INTERVAL, que permite calcular o intervalo entre Datas ou Horas;
– DATETIME combina data e hora em um único tipo, com** intervalo de datas**.
– Por fim, é importante conhecer os valores nulos! Um campo com valor NULL é um campo sem valor. Se um campo em uma tabela for opcional, é possível inserir um novo registro ou atualizar um registro sem adicionar um valor a este campo. Em seguida, o campo será salvo com um valor NULL.
– Observação: um valor NULL é diferente de um valor zero ou de um campo que contém espaços – um campo com um valor NULL é aquele que foi deixado em branco durante a criação do registro.
Sublinguagens SQL
– SQL é uma linguagem que permite realizar determinadas operações em um banco de dados relacional por meio de um conjunto de comandos.
– Em geral, esses comandos são agrupados basicamente em quatro sublinguagens: DDL, DML, DCL e TCL (Também chamada de DTL - Data Transaction Language).
1) DDL (Data Definition Language
– Data Definition Language é o mesmo que Linguagem de Definição de Dados. Logo, essa linguagem serve para definir dados.
– Isso significa que essa linguagem possui um conjunto de comandos que podem ser utilizados para definir um esquema de banco de dados.
– Um esquema é uma descrição da estrutura de um banco de dados, sendo responsável por descrever tabelas, campos, views, funções, entre outros.
– Dito isso, nós podemos afirmar que a DDL é um subconjunto dos comandos SQL que podem ser utilizados para definir ou descrever um esquema de um banco de dados, permitindo criar ou modificar a estrutura de objetos de uma base de dados relacional.
– Portanto, SQL é uma linguagem com vários comandos e os comandos responsáveis por definir essa estrutura são chamados de DDL.
– A DDL define a estrutura física e lógica do banco de dados. Atua sobre objetos como tabelas, índices, visões (views), esquemas e domínios.
– Comandos do DDL:
Comandos DDL
CREATE TABLE
– Esse comando permite criar uma tabela em um banco de dados.
CREATE TABLE NOME_DA_TABELA (
NOME_COLUNA1 TIPO_DE_DADO RESTRIÇÕES ,
NOME_COLUNA2 TIPO_DE_DADO RESTRIÇÕES ,
NOME_COLUNA3 TIPO_DE_DADO RESTRIÇÕES ,
…
)
CREATE TABLE ALUNO (
NOME VARCHAR(20) NOT NULL ,
CPF INT PRIMARY KEY ,
SEXO CHAR(1) NOT NULL ,
DATA_NASCIMENTO DATE NOT NULL ,
CIDADE VARCHAR(50) NOT NULL ,
VALOR_PAGO INT NOT NULL
);
– A sintaxe do comando indica que é necessário especificar o nome da tabela e – para cada coluna – indicar seu nome, tipo de dado e eventuais restrições.
– No exemplo acima, nós criamos uma tabela (ALUNO) que:
- Contém seis colunas (NOME, CPF, SEXO, DATA_NASCIMENTO, CIDADE, VALOR_PAGO).
- Cada coluna possui um tipo (VARCHAR(20), INT, CHAR(1), DATE, VARCHAR(50), INT) e pode armazenar dados apenas desse respectivo tipo.
– Por fim, note que as colunas possuem determinadas restrições.
- Restrições são limitações de uma coluna (Ex: determinada coluna deve ser chave primária; determinada coluna deve ser chave estrangeira; determinada coluna não pode ser nula).
- O resultado do comando é uma tabela com suas respectivas colunas e restrições, mas sem nenhum dado, uma vez que nós apenas criamos a tabela, mas ainda não inserimos nada dentro.
– OBS: É possível criar uma tabela a partir de outra tabela;
CREATE TABLE NOME_TABELA_NOVA AS
SELECT NOME_COLUNA1, NOME_COLUNA2, NOME_COLUNA3, …
FROM NOME_TABELA_ANTIGA
WHERE …
CREATE TABLE ALUNO_ESCOLA_NOVA AS
SELECT NOME, CPF, SEXO, DATA_NASCIMENTO, CIDADE, VALOR_PAGO
FROM ALUNO_ESCOLA_ANTIGA
– Ao criar uma tabela a partir de outra, os dados contidos na tabela original também são copiados para a nova tabela.
Comandos DDL
DROP TABLE
– Esse comando é utilizado para excluir uma tabela existente em um banco de dados.
– Deve ser utilizado com extremo cuidado porque ele apagará a tabela junto com todos os seus dados.
DROP TABLE NOME_DA_TABELA;
DROP TABLE ALUNO_ESCOLA_NOVA;
Comandos DDL
TRUNCATE TABLE
– Esse comando é utilizado para apagar todos os dados de uma tabela, porém sem apagar a tabela em si.
– Em contraste com o comando DROP, aqui a estrutura da tabela permanece inalterada.
TRUNCATE TABLE NOME_DA_TABELA;
TRUNCATE TABLE ALUNO_ESCOLA_NOVA;
Comandos DDL
ALTER TABLE
– Esse comando é utilizado para adicionar, deletar ou modificar colunas de uma tabela existente – assim como permite modificar restrições.
– Para adicionar uma coluna, utilizamos a sintaxe:
ALTER TABLE NOME_DA_TABELA
ADD COLUMN NOME_COLUNA TIPO_DE_DADO;
ALTER TABLE ALUNO
ADD COLUMN EMAIL VARCHAR(255);
– Vejam que nós adicionamos uma coluna do tipo texto chamada EMAIL capaz de armazenar até 255 caracteres.
– Para excluir uma coluna, utilizamos a sintaxe:
ALTER TABLE NOME_DA_TABELA
DROP COLUMN NOME_COLUNA;
ALTER TABLE ALUNO
DROP COLUMN SEXO;
– A coluna SEXO foi excluída do resultado
– Para modificar o tipo de dado uma coluna, utilizamos a sintaxe:
ALTER TABLE NOME_DA_TABELA
ALTER COLUMN NOME_COLUNA TIPODEDADO;
ALTER TABLE NOME_DA_TABELA
MODIFY COLUMN NOME_COLUNA TIPODEDADO;
ALTER TABLE NOME_DA_TABELA
MODIFY NOME_COLUNA TIPODEDADO;
– Há três opções de sintaxe diferentes, porque existem pequenas diferenças a depender do SGBD utilizado.
ALTER TABLE ALUNO
ALTER COLUMN CPF VARCHAR(14);
– Notem que alteramos a coluna CPF da tabela ALUNO.
- Nós apenas convertemos o tipo de dado dessa coluna de INT para VARCHAR.
– Por fim, por meio desse comando, é possível também inserir ou excluir restrições de uma coluna.
- Você pode alterar uma coluna para indicar que ela não pode ser nula ou que ela será uma chave estrangeira.
Comandos DDL
RENAME TABLE
– Em algumas situações, administradores de banco de dados desejam alterar o nome de uma tabela a fim de dar um nome mais relevante ou por outra razão.
RENAME TABLE NOME_DA_TABELA
TO NOVO_NOME_DA_TABELA;
RENAME TABLE ALUNO
TO ALUNO_ESTRATEGIA;
– Alternativamente, também é possível utilizar o comando ALTER TABLE para modificar o nome de uma determinada tabela. Vejamos a sintaxe:
ALTER TABLE NOME_DA_TABELA
RENAME TO NOVO_NOME_DA_TABELA;
ALTER TABLE ALUNO
RENAME TO ALUNO_ESTRATEGIA;
Restrições
– Restrições (Constraints) são um conjunto de limitações utilizadas para especificar regras para os dados em uma tabela de um banco de dados relacional.
– Elas buscam limitar o tipo de dado que pode ser armazenado, o que garante a precisão e confiabilidade aos dados da tabela. Se houver qualquer violação entre a restrição e a ação de dados, a ação será abortada.
– As restrições evitam que determinadas ações violem a integridade da estrutura dos dados especificada no esquema do banco de dados relacional.
– Elas podem ser no nível de coluna ou no nível de tabela, sendo que as restrições de nível de coluna se aplicam a uma coluna e as restrições de nível de tabela se aplicam a toda tabela.
– Principais restrições:
Restrições
NOT NULL
– Por padrão, uma coluna pode conter valores nulos (NULL). Isso significa que – se nada for especificado – não há nenhum problema em existir uma coluna que não contenha nenhum valor.
– Já a restrição NOT NULL força uma coluna a não aceitar valores nulos.
– Em outras palavras, essa restrição obriga que determinada coluna contenha valores. Logo, você não pode inserir um novo registro na tabela (ou atualizar um registro existente) sem adicionar valores a esse campo.
– Existem basicamente duas maneiras de definir uma coluna como NOT NULL.
– A primeira é durante a criação da tabela conforme já vimos anteriormente:
CREATE TABLE NOME_DA_TABELA (
NOME_COLUNA1 TIPODEDADO NOT NULL ,
…
);
CREATE TABLE ALUNO (
NOME VARCHAR(20) NOT NULL ,
CPF INT PRIMARY KEY ,
SEXO CHAR(1) NOT NULL ,
DATA_NASCIMENTO DATE NOT NULL ,
CIDADE VARCHAR(50),
VALOR_PAGO INT
);
– Ao criar uma tabela, nós definimos – para cada coluna – nome, tipo e restrição. Nesse caso, basta definir a coluna como NOT NULL.
– A segunda maneira é por meio do comando ALTER TABLE:
ALTER TABLE ALUNO
MODIFY CIDADE VARCHAR(50) NOT NULL;
– Portanto, a tabela ALUNO não permitirá valores nulos para os campos NOME, CPF, SEXO, DATA_NASCIMENTO e CIDADE.
- Logo, sempre que um registro for incluído nessa tabela, apenas o campo VALOR_PAGO poderá ficar em branco porque nenhuma restrição foi definida para ele.
- Todos os outros obrigatoriamente deverão ser preenchidos, caso contrário violarão a restrição especificada e a operação de inserção será abortada.
– ATENÇÃO: Uma coluna com valor zero ou uma coluna com espaços em branco NÃO SÃO NULAS.
- Nulo significa ausência de valor, isto é, uma coluna vazia.
Restrições
UNIQUE
– Essa restrição garante que todos os valores em uma coluna sejam diferentes.
–Se uma coluna for definida com essa restrição, nenhum registro poderá ter valores iguais nessa coluna.
CREATE TABLE ALUNO (
NOME VARCHAR(20) NOT NULL ,
CPF INT PRIMARY KEY ,
SEXO CHAR(1) NOT NULL ,
DATA_NASCIMENTO DATE NOT NULL ,
CIDADE VARCHAR(50) ,
MATRICULA INT UNIQUE ,
VALOR_PAGO INT
);
CREATE TABLE ALUNO (
NOME VARCHAR(20) NOT NULL ,
CPF INT PRIMARY KEY ,
SEXO CHAR(1) NOT NULL ,
DATA_NASCIMENTO DATE NOT NULL ,
CIDADE VARCHAR(50) ,
MATRICULA INT ,
VALOR_PAGO INT
UNIQUE (MATRICULA)
);
– Note que especificamos que a coluna MATRICULA é UNIQUE.
- Logo, em todos os registros da tabela, essa coluna não pode ficar vazia nem ter valores repetidos.
– É possível dar um nome a uma restrição de unicidade.
– Portanto, é possível nomear uma restrição de unicidade ou defini-la para múltiplas colunas simultaneamente. A sintaxe para ambas as situações é a mesma:
– PARA NOMEAR UMA RESTRIÇÃO OU DEFINI-LA PARA MÚLTIPLAS COLUNAS
CREATE TABLE NOME_DA_TABELA (
NOME_COLUNA1 TIPO_DE_DADO PRIMARY KEY ,
NOME_COLUNA2 TIPO_DE_DADO NOT NULL ,
NOME_COLUNA3 TIPO_DE_DADO ,
NOME_COLUNA4 TIPO_DE_DADO NOT NULL ,
NOME_COLUNA5 TIPO_DE_DADO ,
**CONSTRAINT **NOME_DA_RESTRICAO UNIQUE (NOME_COLUNA3, NOME_COLUNA5)
…
);
– É possível também adicionar uma restrição de unicidade a uma coluna de uma tabela pré-existente por meio da sintaxe apresentada a seguir:
ALTER TABLE NOME_DA_TABELA
ADD UNIQUE (NOME_DA_COLUNA);
– O que aconteceria se eu tentasse inserir uma restrição de unicidade a uma coluna que já possua valores repetidos?
- Antes de inserir a restrição, o Sistema Gerenciador de Banco de Dados (SGBD) analisará os dados da coluna para garantir que todos os valores pré-existentes nela são únicos.
- Se ela encontrar algum valor duplicado, retornará um erro e não alterará a tabela com a adição da restrição de unidade.
– Por fim, da mesma forma que é possível adicionar uma restrição de unicidade a uma determinada coluna, é também possível retirá-la por meio da seguinte sintaxe:
ALTER TABLE NOME_DA_TABELA
DROP INDEX NOME_DA_RESTRICAO;
ALTER TABLE NOME_DA_TABELA
DROP CONSTRAINT NOME_DA_RESTRICAO;
Restrições
PRIMARY KEY
– Essa restrição permite identificar unicamente cada registro de uma tabela, o que fornece uma garantia de exclusividade para uma coluna ou conjunto de colunas.
– A restrição PRIMARY KEY combina as duas restrições analisadas nos tópicos anteriores: PRIMARY KEY = NOT NULL + UNIQUE.
– Em outras palavras, uma coluna que seja definida com a restrição PRIMARY KEY necessariamente não poderá receber valores nulos nem repetidos.
– Uma coluna que possua a restrição UNIQUE
jamais poderá se repetir, mas poderá ser nula;
– Uma coluna que possua a restrição NOT NULL jamais poderá ser nula, mas poderá se repetir;
– Uma coluna que possua a restrição PRIMARY KEY jamais poderá ser nula e jamais poderá se repetir.
– Uma tabela poderá ter apenas uma chave primária composta de **uma coluna **(simples) ou mais colunas (composta).
CREATE TABLE NOME_DA_TABELA (
NOME_COLUNA1 TIPO_DE_DADO PRIMARY KEY ,
NOME_COLUNA2 TIPO_DE_DADO RESTRIÇÕES ,
NOME_COLUNA3 TIPO_DE_DADO RESTRIÇÕES ,
…
);
CREATE TABLE NOME_DA_TABELA (
NOME_COLUNA1 TIPO_DE_DADO RESTRIÇÕES ,
NOME_COLUNA2 TIPO_DE_DADO RESTRIÇÕES ,
NOME_COLUNA3 TIPO_DE_DADO RESTRIÇÕES ,
…
PRIMARY KEY (NOME_COLUNA1)
);
– PARA NOMEAR UMA RESTRIÇÃO OU DEFINI-LA PARA MÚLTIPLAS COLUNAS
CREATE TABLE NOME_DA_TABELA (
NOME_COLUNA1 TIPO_DE_DADO RESTRIÇÕES ,
NOME_COLUNA2 TIPO_DE_DADO RESTRIÇÕES ,
NOME_COLUNA3 TIPO_DE_DADO RESTRIÇÕES ,
…
CONSTRAINT NOME_DA_RESTRICAO PRIMARY KEY (NOME_COLUNA1, NOME_COLUNA2)
);
– É possível também adicionar uma restrição PRIMARY KEY a uma tabela pré-existente. Para tal, utiliza-se a seguinte sintaxe:
ALTER TABLE NOME_DA_TABELA
ADD PRIMARY KEY (NOME_COLUNA1);
– PARA NOMEAR UMA RESTRIÇÃO OU DEFINI-LA PARA MÚLTIPLAS COLUNAS
ALTER TABLE NOME_DA_TABELA
ADD CONSTRAINT NOME_DA_RESTRICAO PRIMARY KEY (NOME_COLUNA1, NOME_COLUNA2);
– Por fim, da mesma forma que é possível adicionar uma restrição PRIMARY KEY a uma determinada coluna, é também possível retirá-la por meio da seguinte sintaxe:
ALTER TABLE NOME_DA_TABELA
DROP PRIMARY KEY;
ALTER TABLE NOME_DA_TABELA
DROP CONSTRAINT NOME_DA_RESTRICAO;
Restrições
FOREIGN KEY
– As tabelas dentro de um banco de dados relacional precisam se interligar de alguma forma.
- Essa ligação se faz por meio de chaves estrangeiras.
- As chaves estrangeiras são utilizadas para unir duas tabelas, em que a chave estrangeira de uma tabela referencia uma chave candidata de outra tabela (em geral, a chave primária).
– A restrição FOREIGN KEY é utilizada justamente para definir uma ou mais colunas como chaves estrangeiras e prevenir que alguma ação possa destruir essa ligação entre tabelas.
– A tabela com a chave estrangeira é chamada de Tabela Filha, e a tabela com a chave primária é chamada de Tabela Referenciada ou Tabela Pai.
CREATE TABLE NOME_DA_TABELA (
NOME_COLUNA1 TIPO_DE_DADO PRIMARY KEY ,
NOME_COLUNA2 TIPO_DE_DADO RESTRIÇÕES ,
NOME_COLUNA3 TIPO_DE_DADO FOREIGN KEY REFERENCES TABELA_REFERENCIADA (CHAVE)
);
CREATE TABLE NOME_DA_TABELA (
NOME_COLUNA1 TIPO_DE_DADO RESTRIÇÕES ,
NOME_COLUNA2 TIPO_DE_DADO RESTRIÇÕES ,
NOME_COLUNA3 TIPO_DE_DADO RESTRIÇÕES ,
PRIMARY KEY (NOME_COLUNA1) ,
FOREIGN KEY (NOME_COLUNA2) REFERENCES TABELA_REFERENCIADA (CHAVE)
);
– PARA NOMEAR UMA RESTRIÇÃO OU DEFINI-LA PARA MÚLTIPLAS COLUNAS
CREATE TABLE NOME_DA_TABELA (
NOME_COLUNA1 TIPO_DE_DADO RESTRIÇÕES ,
NOME_COLUNA2 TIPO_DE_DADO RESTRIÇÕES ,
NOME_COLUNA3 TIPO_DE_DADO RESTRIÇÕES ,
CONSTRAINT NOME_DA_RESTRICAO FOREIGN KEY (NOME_COLUNA1)
REFERENCES TABELA_REFERENCIADA (CHAVE)
);
– As sintaxes apresentadas anteriormente atribuímos a restrição FOREIGN KEY a uma coluna da Tabela Filha e definimos à qual coluna ela se refere na Tabela Referenciada.
- É a coluna de uma tabela se referindo à coluna de outra tabela de modo que uma alteração em uma também afeta a outra.
– É possível adicionar essa restrição a uma tabela pré-existente:
ALTER TABLE NOME_DA_TABELA
ADD FOREIGN KEY (NOME_COLUNA1) REFERENCES TABELA_REFERENCIADA (CHAVE);
– PARA NOMEAR UMA RESTRIÇÃO OU DEFINI-LA PARA MÚLTIPLAS COLUNAS
ALTER TABLE NOME_DA_TABELA
ADD CONSTRAINT NOME_DA_RESTRICAO
FOREIGN KEY (NOME_COLUNA1)
REFERENCES TABELA_REFERENCIADA (CHAVE);
– Por fim, da mesma forma que é possível adicionar uma restrição FOREIGN KEY a uma determinada coluna, é também possível retirá-la por meio da seguinte sintaxe:
ALTER TABLE NOME_DA_TABELA
DROP FOREIGN KEY;
ALTER TABLE NOME_DA_TABELA
DROP CONSTRAINT NOME_DA_RESTRICAO;
– Problema: O que aconteceria se eu deletasse um registro da tabela pai?
- Todo registro da tabela filha que referenciasse esse registro deletado da tabela pai teria um valor inválido, porque ela perderia a sua referência.
- Para resolver esse problema podemos utilizar a cláusula ON DELETE CASCADE.
- => Essa cláusula basicamente obriga a exclusão dos registros correspondentes das Tabelas Filhas que referenciam o registro excluído da Tabela Pai.
– Existe também a cláusula ON UPDATE, que permite realizar algumas ações quando há uma alteração na tabela pai: CASCADE, RESTRICT, NO ACTION, SET NULL e SET DEFAULT.
Restrições
CHECK
– Essa restrição é utilizada para limitar o intervalo de valores que pode ser inserido em uma coluna.
- É possível defini-la para uma coluna ou para uma tabela.
- Caso seja definida para uma coluna, ela permitirá apenas alguns valores para esta coluna.
- Caso seja definida para uma tabela, ela limitará os valores de certas colunas com base nos valores de outras colunas da linha.
CREATE TABLE ALUNO (
NOME VARCHAR(20) NOT NULL ,
CPF INT PRIMARY KEY ,
SEXO CHAR(1) NOT NULL ,
CIDADE VARCHAR(50) ,
MATRICULA INT UNIQUE ,
IDADE INT CHECK (IDADE >= 18)
);
CREATE TABLE ALUNO (
NOME VARCHAR(20) NOT NULL ,
CPF INT PRIMARY KEY ,
SEXO *CHAR(1) *NOT NULL ,
CIDADE VARCHAR(50) ,
MATRICULA INT UNIQUE ,
IDADE INT ,
CHECK (IDADE >= 18)
);
– PARA NOMEAR UMA RESTRIÇÃO OU DEFINI-LA PARA MÚLTIPLAS COLUNAS
CREATE TABLE ALUNO (
NOME VARCHAR(20) NOT NULL ,
CPF INT PRIMARY KEY ,
SEXO CHAR(1) NOT NULL ,
CIDADE VARCHAR(50) ,
MATRICULA INT UNIQUE ,
IDADE INT ,
CONSTRAINT NOME_DA_RESTRICAO CHECK (IDADE >= 18 AND SEXO = ‘F’)
);
– No último exemplo, temos uma restrição composta, dado que limita a inserção de registros apenas àqueles que tenham IDADE >= 18 e SEXO = ‘F’. Em outras palavras, será permitido o armazenamento de registros apenas de mulheres maiores de idade.
– Também é possível adicioná-la após a criação da tabela, isto é, em uma tabela pré-existente.
ALTER TABLE NOME_DA_TABELA
ADD CHECK (CONDICAO);
– PARA NOMEAR UMA RESTRIÇÃO OU DEFINI-LA PARA MÚLTIPLAS COLUNAS
ALTER TABLE NOME_DA_TABELA
ADD CONSTRAINT NOME_DA_RESTRICAO CHECK (CONDICAO1 OPERADOR CONDIÇÃO2 …);
– Da mesma forma que é possível adicionar uma restrição de checagem, é também possível retirá-la por meio da seguinte sintaxe:
ALTER TABLE NOME_DA_TABELA
DROP CHECK NOME_DA_RESTRICAO;
ALTER TABLE NOME_DA_TABELA
DROP CONSTRAINT NOME_DA_RESTRICAO;
Restrições
DEFAULT
– Essa restrição é utilizada para configurar um valor padrão para uma coluna.
– Esse valor padrão é adicionado em todos os novos registros, caso nenhum outro valor tenha sido especificado.
CREATE TABLE ALUNO (
NOME VARCHAR(20) NOT NULL ,
CPF INT PRIMARY KEY ,
SEXO CHAR(1) NOT NULL ,
CIDADE VARCHAR(50) DEFAULT ‘Brasília’ ,
MATRICULA INT UNIQUE ,
);
– No exemplo acima, todo registro que não tenha especificado um valor para a coluna CIDADE será automaticamente preenchido com o valor Brasília pelo próprio sistema.
ALTER TABLE NOME_DA_TABELA
ADD NOME_COLUNA SET DEFAULT VALOR;
ALTER TABLE NOME_DA_TABELA
ADD CONSTRAINT NOME_DA_RESTRICAO DEFAULT VALOR FOR NOME_COLUNA;
ALTER TABLE NOME_DA_TABELA
ALTER COLUMN NOME_COLUNA SET DEFAULT VALOR;
ALTER TABLE NOME_DA_TABELA
MODIFY NOME_COLUNA DEFAULT VALOR;
– Da mesma forma que é possível adicionar um valor padrão, é também possível retirá-lo por meio da seguinte sintaxe:
ALTER TABLE NOME_DA_TABELA
ALTER NOME_COLUNA DROP DEFAULT;
**ALTER TABLE **NOME_DA_TABELA
ALTER COLUMN NOME_COLUNA DROP DEFAULT;
DML (Data Manipulation Language)
– Data Manipulation Language (em tradução livre, Linguagem de Manipulação de Dados).
– Essa linguagem serve manipular dados.
– Possui um conjunto de comandos que podem ser utilizados para realizar transações em um banco de dados (inserir, excluir, deletar ou consultar):
Comandos DML
INSERT
– Esse comando é utilizado para inserir novos registros em uma tabela do banco de dados.
– Há duas formas de inseri-los: completo ou incompleto.
– Imagine uma tabela cujos registros contenham seis colunas:
- Se você for inserir um registro por completo, isto é, com valores para todas as colunas, não é necessário indicar o nome das colunas;
- Se for inserir dados para apenas algumas colunas, é necessário indicar quais serão essas colunas e na ordem correta.
– INSERÇÃO DE TODOS OS VALORES DISPENSA A ESPECIFICAÇÃO DAS COLUNAS
INSERT INTO NOME_DA_TABELA
VALUES (VALOR_1, VALOR_2, VALOR_3, …)
– INSERÇÃO DE VALORES PARA APENAS ALGUMAS COLUNAS, PRECISA DA ESPECIFICAÇÃO
INSERT INTO NOME_DA_TABELA (NOME_COLUNA1, NOME_COLUNA2, NOME_COLUNA3, …)
VALUES (VALOR_1, VALOR_2, VALOR_3, …)
Comandos DML
UPDATE
– Esse comando é utilizado para atualizar registros existentes em uma tabela do banco de dados.
– Esse comando é utilizado para atualizar registros existentes em uma tabela do banco de dados.
– Pode-se atualizar todos os registros de uma tabela ou apenas alguns.
- Para atualizar registros específicos, devemos utilizar a cláusula WHERE.
- Essa cláusula será detalhada mais à frente, mas – por enquanto – basta saber que ela permite filtrar dados a partir de um conjunto de condições.
UPDATE NOME_DA_TABELA
SET NOME_DA_COLUNA_1 = VALOR_1, NOME_COLUNA2 = VALOR_2 …
WHERE LISTA_DE_CONDICOES
UPDATE ALUNO_ESTRATEGIA
SET NOME = ‘DIOGO’, EMAIL = ‘DIOGO@GMAIL.COM’
WHERE CPF = 44444444444
– Vamos supor que houvesse um erro e o nome de um aluno fosse Diogo em vez de Diego.
- Vejam no exemplo acima que o código apresentado atualiza (UPDATE) a tabela ALUNO_ESTRATEGIA de tal forma que se configure (SET) o valor da coluna NOME para ‘Diogo’ e o valor da coluna EMAIL para ‘diogo@gmail.com’, porém apenas para os registros que tenham 44444444444 como valor de CPF.
Comandos DML
DELETE
– Esse comando é utilizado para deletar registros existentes em uma tabela do banco de dados.
- Pode-se deletar todos os registros de uma tabela ou apenas alguns.
– Para deletar registros específicos, devemos utilizar a cláusula WHERE.
- Se não for utilizada a cláusula WHERE, o DELETE funcionará como um TRUNCATE. => Irá deletar todos os registros de uma tabela (mas mantém a estrutura).
DELETE FROM NOME_DA_TABELA WHERE LISTA_DE_CONDICOES
DELETE FROM ALUNO_ESTRATEGIA WHERE VALOR_PAGO = 175.00 OR CIDADE = ‘RECIFE’;
Comandos DML
SELECT
– Esse comando é utilizado para recuperar informações de um banco de dados.
– ATENÇÃO: não confundir a cláusula SELECT com a operação de seleção da álgebra relacional.
– Na verdade, essas três operações podem ser mapeadas para suas cláusulas correspondentes como SELECT, FROM e WHERE respectivamente.
-Sintaxe do comando
– AS CLÁUSULAS SÃO OPCIONAIS
SELECT LISTA_DE_COLUNAS FROM LISTA_DE_TABELAS CLAUSULAS;
SELECT * FROM ALUNO_ESTRATEGIA
– Note que foi utilizado o elemento asterisco (*). => significa que queremos recuperar todas as colunas da tabela.
– Comandos e respectiva interpretação:
SELECT NOME, DATA_NASCIMENTO FROM ALUNO_ESTRATEGIA;
– Existe uma palavra-chave que pode ser utilizada junto com o comando SELECT que tem a função justamente de eliminar os registros duplicados. Essa palavra-chave se chama DINSTINCT.
– AS CLÁUSULAS SÃO OPCIONAIS
SELECT DISTINCT LISTA_DE_COLUNAS FROM LISTA_DE_TABELAS CLAUSULAS;
SELECT DISTINCT CIDADE FROM ALUNO_ESTRATEGIA;
– Nesse caso, a partir do acréscimo do DISTINCT, só irá retornar valores não repetidos.
– Alias => Trata-se de um recurso utilizado para dar a uma tabela (ou a uma coluna de uma tabela) um nome temporário – como se fosse um apelido.
- Em geral, eles são utilizados para tornar os nomes das colunas mais legíveis.
- Um alias existe apenas para a duração de uma determinada consulta e é criado por meio da palavra-chave AS (que pode ser omitida).
– ALIAS PARA O NOME DA TABELA
SELECT NOME_COLUNA FROM NOME_DA_TABELA AS APELIDO CLAUSULAS;
– ALIAS PARA O NOME DA COLUNA
SELECT NOME_COLUNA AS APELIDO FROM NOME_DA_TABELA CLAUSULAS;
SELECT NOME AS N, DATA_NASCIMENTO AS DN FROM ALUNO_ESTRATEGIA AS AE;
– Em geral, esse recurso é muito útil quando existe mais de uma tabela envolvida em uma consulta; quando funções são utilizadas dentro de uma consulta; quando nomes de colunas são muito grandes ou pouco intuitivos; e quando duas ou mais colunas são combinadas em uma só.
– Uma outra possibilidade é a inserção de constantes em vez de nomes de tabelas. => é possível pedir para a consulta retornar uma constante para cada registro da tabela.
SELECT 1 AS RESULTADO FROM ALUNO_ESTRATEGIA;
Cláusulas - FROM
– As cláusulas SQL são partes específicas de um comando (geralmente SELECT) que indicam o que deve ser buscado, de onde, com quais filtros, ordenações, agrupamentos, etc.
– São como blocos de construção das consultas SQL.
1) FROM
– Especifica de onde (quais tabelas) devemos selecionar ou excluir dados – aqui vamos nos focar apenas na seleção de dados.
SELECT LISTA_DE_COLUNAS FROM TABELA1, TABELA2, … CLAUSULAS;
– É possível especificar mais de uma tabela separada por vírgula! Quando isso ocorre,
temos um Produto Cartesiano.
SELECT * FROM TABELA_PROFESSOR, TABELA_DISCIPLINA;
– As colunas da tabela resultante é basicamente a união das colunas das tabelas especificadas, uma vez que utilizamos o asterisco.
- Já linhas da tabela resultante é basicamente uma combinação de todas as linhas de uma tabela com todas as linhas de outra.
- Chama-se produto cartesiano justamente porque o resultado é um produto, isto é, o número de linhas de uma tabela (3) vezes o número de linhas de outra tabela (2) retorna uma tabela resultante com 3x2 = 6 linhas.
– Quando fazemos combinações entre tabelas, os apelidos (alias) se tornam extremamente úteis.
- Porque eventualmente podemos fazer o produto de duas ou mais tabelas que possuem atributos com o mesmo nome.
– Exemplo: Imagine o produto cartesiano entre uma tabela chamada PRODUTO e outra tabela chamada EMPRESA.
- Imagine que ambas as tabelas possuem uma coluna chamada CÓDIGO.
- Nesse caso, a tabela resultante teria duas colunas com o mesmo nome.
- Para evitar esse tipo de problema e reduzir a ambiguidade, utilizam-se os alias.
- Nós podemos chamar a tabela PRODUTO de P e a tabela EMPRESA de E.
- Dessa forma, a tabela resultante teria uma coluna P.CODIGO e outra coluna chamada E.CODIGO. E assim não temos mais ambiguidade.
Cláusulas
JOIN
– Essa cláusula é utilizada para combinar linhas/registros de duas ou mais tabelas, com base em uma coluna em comum entre elas.
– Possui 5 tipos diferentes:
1) INNER JOIN
– O INNER JOIN (também chamado apenas de JOIN) é uma cláusula que seleciona registros que contenham valores correspondentes em ambas as tabelas.
– O comando permite utilizar INNER JOIN ou apenas JOIN.
SELECT NOME_DAS_COLUNAS
FROM TABELA1
INNER JOIN TABELA2
ON TABELA1.NOME_COLUNA = TABELA2.NOME_COLUNA;
SELECT PEDIDOS.ID_PEDIDO, CLIENTES.NOME_CLIENTE
FROM PEDIDOS
INNER JOIN CLIENTES
ON PEDIDOS.ID_CLIENTE = CLIENTES.ID_CLIENTE;
– O comando está nos dizendo para selecionar (SELECT) todas as linhas de ambas as tabelas (FROM PEDIDOS INNER JOIN CLIENTES) desde que exista uma correspondência entre as colunas (ON PEDIDOS.ID_CLIENTE = CLIENTES.ID_CLIENTE) e, após isso, retornar as colunas PEDIDOS.ID_PEDIDO e CLIENTES.NOME_CLIENTE.
– No exemplo, a coluna em comum é
ID_CLIENTE.
- A tabela PEDIDOS possui três valores para essa coluna: [2, 37, 77];
- A tabela CLIENTES também possui três valores para essa coluna: [1, 2, 3].
- Como se trata de um INNER JOIN, a tabela resultante retornará apenas os registros que possuem correspondência em ambas as tabelas.
– Também que é possível fazer um INNER JOIN com mais de duas tabelas, conforme mostra o exemplo seguinte (com três tabelas):
SELECT PEDIDOS.ID_PEDIDO, CLIENTES.NOME_CLIENTE, ENTREGADORES.NOME_ENTREGADOR
FROM ((PEDIDOS
INNER JOIN CLIENTES ON PEDIDOS.ID_CLIENTE = CLIENTES.ID_CLIENTE)
INNER JOIN ENTREGADORES ON PEDIDOS.ID_ENTREGADOR = ENTREGADORES.ID_ENTREGADOR);
– As tabelas que compõem um INNER JOIN devem possuir uma coluna em comum.
- Em geral, essas colunas em comum possuem o mesmo nome conforme vimos nos exemplos.
- No entanto, isso não é obrigatório – elas podem ter conteúdos correspondentes, mas nomes distintos.
- De toda forma, caso elas tenham o mesmo nome, é possível utilizar a palavra-chave USING para melhorar a leitura do código e sua compreensão.
SELECT LISTA_DE_COLUNAS
FROM TABELA1
INNER JOIN TABELA2
USING (NOME_COLUNA_COMUM);
SELECT PEDIDOS.ID_PEDIDO, CLIENTES.NOME_CLIENTE
FROM PEDIDOS
INNER JOIN CLIENTES
USING (ID_CLIENTE);
2) LEFT JOIN
– O LEFT JOIN (também chamado de LEFT OUTER JOIN) retorna todos os registros da tabela da esquerda, além dos registros correspondentes da tabela da direita.
SELECT NOME_DAS_COLUNAS
FROM TABELA1
LEFT JOIN TABELA2
ON TABELA1.NOME_COLUNA = TABELA2.NOME_COLUNA;
SELECT PEDIDOS.ID_PEDIDO, CLIENTES.NOME_CLIENTE
FROM PEDIDOS
LEFT JOIN CLIENTES
ON PEDIDOS.ID_CLIENTE = CLIENTES.ID_CLIENTE;
– O comando está nos dizendo para selecionar (SELECT) todas as linhas da tabela da esquerda (FROM PEDIDOS LEFT JOIN), além dos registros da tabela da direita (CLIENTES) desde que exista uma correspondência entre as colunas (ON PEDIDOS.ID_CLIENTE = CLIENTES.ID_CLIENTE) e, após isso, retornar as colunas PEDIDOS.ID_PEDIDO e CLIENTES.NOME_CLIENTE.
3) RIGHT JOIN
– O RIGHT JOIN (também chamado de RIGHT OUTER JOIN) retorna todos os registros da tabela da direita, além dos registros correspondentes da tabela da esquerda.
SELECT NOME_DAS_COLUNAS
FROM TABELA1
RIGHT JOIN TABELA2
ON TABELA1.NOME_COLUNA = TABELA2.NOME_COLUNA;
SELECT PEDIDOS.ID_PEDIDO, CLIENTES.NOME_CLIENTE
FROM PEDIDOS
RIGHT JOIN CLIENTES
ON PEDIDOS.ID_CLIENTE = CLIENTES.ID_CLIENTE;
– O comando está nos dizendo para selecionar (SELECT) todas as linhas da tabela da direita (CLIENTES), além dos registros da tabela da esquerda (FROM PEDIDOS RIGHT JOIN) desde que exista uma correspondência entre as colunas (ON PEDIDOS.ID_CLIENTE = CLIENTES.ID_CLIENTE) e, após isso, retornar as colunas PEDIDOS.ID_PEDIDO e CLIENTES.NOME_CLIENTE.
4) FULL JOIN (ou FULL OUTER JOIN)
– O FULL JOIN (também chamado de FULL OUTER JOIN) retorna todos os registros quando há uma correspondência da tabela esquerda com a direita ou da direita com a esquerda.
SELECT NOME_DAS_COLUNAS
FROM TABELA1
FULL OUTER JOIN TABELA2
ON TABELA1.NOME_COLUNA = TABELA2.NOME_COLUNA;
SELECT PEDIDOS.ID_PEDIDO, CLIENTES.NOME_CLIENTE
FROM PEDIDOS
FULL OUTER JOIN CLIENTES
ON PEDIDOS.ID_CLIENTE = CLIENTES.ID_CLIENTE;
– O comando está nos dizendo para selecionar (SELECT) todas as linhas da tabela da direita e da esquerda (FROM PEDIDOS FULL OUTER JOIN CLIENTES) desde que exista uma correspondência entre as colunas (ON PEDIDOS.ID_CLIENTE = CLIENTES.ID_CLIENTE) e, após isso, retornar as colunas PEDIDOS.ID_PEDIDO e CLIENTES.NOME_CLIENTE.
5) SELF JOIN
– Por fim, o SELF JOIN é um join comum, mas que relaciona uma tabela consigo mesma. Imaginem um auto-relacionamento, isto é, uma tabela que se relaciona com ela mesma.
SELECT C1.NOME_CLIENTE AS CLIENTE_INDICADOR, C2.NOME_CLIENTE AS CLIENTE_INDICADO
FROM CLIENTES C1
JOIN CLIENTES C2
ON C1.ID_CLIENTE = C2.ID_INDICACAO;