---
# System prepended metadata

title: SQL Tutorial
tags: [sql, sefaz/al]

---

# SQL Tutorial

## INTRODUÇÃO AO SQL

### Tabelas de banco de dados relacional
Em um banco de dados relacional, os dados são armazenados em tabelas. Como exemplo, a tabela abaixo possui dados em 4 linhas e 3 colunas.

![](https://i.imgur.com/DKahR29.png)

### Bancos de Dados SQL e Relacionais
Um banco de dados relacional contém tabelas que armazenam dados relacionados de alguma forma. SQL é a linguagem que permite a recuperação e manipulação de dados de tabelas em um banco de dados relacional.

A base de dados abaixo possui 2 tabelas: uma com dados de Users e outra com dados de Products . SQL é a linguagem com a qual você recupera dados, atualiza dados e remove dados.

![](https://i.imgur.com/6skJnaw.png)

### Banco de dados de exemplo
Neste exemplo temos uma loja fictícia que vende produtos alimentícios especiais de todo o mundo. O banco de dados possui 5 tabelas com informações de Produtos, Fornecedores, Clientes e Pedidos.

Este Diagrama Entidade Relacionamento (ERD) mostra as tabelas e seus relacionamentos.

![](https://i.imgur.com/mZpDTb6.png)

Os diagramas ERD são uma ferramenta importante para profissionais de dados: eles fornecem uma riqueza de informações sobre tabelas, colunas, tipos de dados, relacionamentos, chaves primárias, chaves estrangeiras e índices -- tudo em um único diagrama.

## SQL SINTAXE
* As instruções SQL são consultas de banco de dados semelhantes ao inglês .
* As palavras-chave incluem SELECT, UPDATE, WHERE, ORDER BY, etc.
* ANSI Standard SQL é a língua franca para bancos de dados relacionais.

**Exemplo de SQL**
Liste todos os clientes na Itália.
```sql=
SELECT FirstName, LastName, City, Country
  FROM Customer
 WHERE Country = 'Italy'
``` 

### Usando SQL
Muitas pessoas não sabem disso, mas o SQL foi originalmente projetado para ser inserido em um console e os resultados seriam exibidos em uma tela. Daí o inglês como sintaxe.

No entanto, isso nunca aconteceu porque, ao digitar incorretamente uma consulta, o operador poderia causar grandes danos ao banco de dados. Imagine digitar 'DELETE Customer WHERE Id = 1442', mas acidentalmente apertar a tecla Enter após a palavra 'Customer'.

Hoje, o SQL é usado principalmente por programadores que usam o SQL embutido em seus programas para criar aplicativos que requerem dados de um banco de dados.

### CRUD
SQL suporta quatro operações fundamentais, coletivamente conhecidas como CRUD (Create, Read, Update, Delete). Eles são:
* SELECT  -- Ler os dados
* INSERT  -- Inserir novos dados
* UPDATE  -- Atualiza dados existentes
* APAGAR  -- Remover dados

CRUD é um conceito importante porque dá aos usuários controle total sobre seus dados. Ele permite que eles recuperem, adicionem, atualizem e removam qualquer item de dados. A seguir, revisaremos cada uma das operações CRUD.

### Sintaxe SQL select
A forma geral de uma instrução SELECT.
```sql=
coluna SELECT - nomes
  Tabela FROM - nome
ONDE condição
ORDER BY classificar - ordem
```

**Exemplo**
Liste todos os clientes em Paris classificados por sobrenome.
```sql=
SELECT FirstName, LastName, City, Country 
  FROM Customer
 WHERE City = 'Paris'
 ORDER BY LastName
```

### Sintaxe SQL insert
A forma geral de uma instrução INSERT.
```sql=
INSERT nome - da-tabela ( nomes -da - coluna )
VALUES ( coluna - valores )
```

**Exemplo**
Adicionar Oxford Trading à lista de fornecedores.
```sql=
INSERT Supplier (CompanyName, ContactName, City, Country)
VALUES ('Oxford Trading', 'Ian Smith', 'Oxford', 'UK')
```

### Sintaxe SQL update
A forma geral de uma instrução UPDATE.
```sql=
Tabela UPDATE - nome
   SET coluna - nome = coluna - valor
ONDE condição
```

**Exemplo**
O fornecedor com id 24 foi movido. Mude sua cidade de Sydney para Melbourne.
```sql=
UPDATE Supplier
   SET City = 'Melbourne'
 WHERE Id = 24
```

### Sintaxe SQL delete 
A forma geral de uma instrução DELETE.
```sql=
DELETE tabela - nome
ONDE condição
```

**Exemplo**
Remova 'Stroopwafels' dos produtos.
```sql=
DELETE Product
 WHERE ProductName = 'Stroopwafels'
```

## SQL STORED PROCEDURES - SQL SERVER

* Um procedimento armazenado é um bloco nomeado de código SQL.
* Os procedimentos armazenados podem ser reutilizados e executados a qualquer momento.
* Para criar um procedimento armazenado, use o comando CREATE PROCEDURE.
* Os procedimentos armazenados são executados com o comando EXECUTE.

**Exemplo**
Este procedimento armazenado retorna uma lista de clientes que solicitaram produtos de fornecedores em seu próprio país. Este procedimento aceita um argumento Country.
```sql=
CREATE PROCEDURE InCountryCustomers
 @Country NVARCHAR(40)
AS
 BEGIN
  SELECT DISTINCT FirstName, LastName, C.Country
    FROM Customer C
    JOIN [Order] O ON C.Id = O.CustomerId
    JOIN OrderItem I ON O.Id = I.OrderId
    JOIN Product P ON I.ProductId = P.Id
    JOIN Supplier S ON P.SupplierId = S.Id
   WHERE C.Country = @Country 
     AND S.Country = C.Country
 END
```
*O procedimento acima é uma instrução SELECT reutilizável com 5 JOINs de tabela. Ele oferece flexibilidade ao fornecer um parâmetro de país.*

### Executando o procedimento
Para executar um procedimento use o EXECUTEcomando, assim:
```sql=
EXECUTE InCountryCustomers 'France'
```
*Isso retorna todos os clientes na França que encomendaram produtos de fornecedores franceses.*

### Usando Stored Procedures
* Um procedimento armazenado é um programa T-SQL com instruções SQL e lógica opcional.
* Um procedimento armazenado representa código SQL reutilizável que pode ser executado repetidamente.
* Procedimentos armazenados são objetos de banco de dados armazenados no servidor de banco de dados.
* Procedimentos armazenados podem aceitar parâmetros.

### Sintaxe
Sintaxe para criar um procedimento armazenado.
```sql=
CREATE PROCEDURE nome_do_procedimento
COMO
 COMEÇAR
  sql_statement
 FIM
```
* *procedure_name-- o nome atribuído ao procedimento.*
* *sql_statement-- qualquer consulta SQL válida ou bloco de código T-SQL (Transact-SQL).*

Sintaxe para executar um procedimento armazenado.
```sql=
EXECUTE nome_do_procedimento
```

Ou, use a abreviação.
```sql=
EXEC nome_do_procedimento
```

Sintaxe para alterar um procedimento armazenado.
```sql=
ALTER PROCEDURE nome_do_procedimento
COMO
 COMEÇAR
  sql_statement
 FIM
```
*Isso substitui efetivamente a versão anterior do procedimento armazenado.

Sintaxe para remover um procedimento armazenado.
```sql=
DROP PROCEDURE nome_do_procedimento
```

**Exemplo**
`CREATE PROCEDURE`
Crie um procedimento que liste todos os fornecedores e seus produtos.
![](https://i.imgur.com/QL5Tr9C.png)
```sql=
CREATE PROCEDURE SupplierProducts
AS
 BEGIN
  SELECT CompanyName, ProductName, UnitPrice, Package
    FROM Supplier S
    JOIN Product P ON P.SupplierId = S.Id
   ORDER BY CompanyName
 END 
```

**Exemplo**
`EXECUTE PROCEDURE`
Execute o procedimento SupplierProducts acima.
```sql=
EXEC SupplierProducts
```

**Exemplo**
`UPDATE PROCEDURE`
Altere o procedimento SupplierProducts para adicionar uma coluna Country.
```sql=
ALTER PROCEDURE SupplierProducts
AS
 BEGIN
  SELECT CompanyName, ProductName, UnitPrice, 
         Package, Country
    FROM Supplier S
    JOIN Product P ON P.SupplierId = S.Id
   ORDER BY CompanyName
 END 
```

**Exemplo**
`DROP PROCEDURE`
Remova o procedimento armazenado SupplierProducts.
```sql=
DROP PROCEDURE SupplierProducts
```

**Exemplo**
`RENAME PROCEDURE`
Renomeie o procedimento armazenado SupplierProducts para ProductsBySupplier.
```sql=
DROP PROCEDURE SupplierProducts

CREATE PROCEDURE ProductsBySupplier
AS
 BEGIN
  SELECT CompanyName, ProductName, UnitPrice, Package
    FROM Supplier S
    JOIN Product P ON P.SupplierId = S.Id
   ORDER BY CompanyName
 END 
```

### T-SQL e procedimentos armazenados
* T-SQL, ou Transact-SQL, é uma extensão do SQL disponível no SQL Server.
* É uma linguagem de programação básica com variáveis, controle de fluxo, try-catch e muito mais.
* O T-SQL é frequentemente usado em procedimentos armazenados.

Abaixo está um procedimento armazenado T-SQL simples com uma instrução if.
```sql=
CREATE PROCEDURE ListCustomers
  @top INT,
  @full BIT
AS
 BEGIN
  IF (@full = 1)
  BEGIN
   SELECT TOP (@top) *
     FROM Customer
  END
  ELSE
  BEGIN
    SELECT TOP (@top) FirstName, LastName
     FROM Customer
  END
END
```

Para executar o procedimento acima, use EXECUTEcom dois parâmetros, assim: (verdadeiro é convertido em 1).
```sql=
EXECUTE ListaClientes 5 , verdadeiro 
```

### Listar todos os stored procedure
Esta é uma maneira de listar todos os procedimentos armazenados gerados pelo usuário:
```sql=
SELECT * 
  FROM sys.procedures
```

E de outra maneira.
```sql=
SELECT * 
  FROM INFORMATION_SCHEMA.ROUTINES  
 WHERE ROUTINE_TYPE = 'PROCEDURE'
```

### Benefícios dos stored procedure
* Eficiência. Quando executados pela primeira vez, eles criam um plano que é armazenado em cache.
* Reutilização. Os procedimentos armazenados podem ser usados várias vezes.
* Tráfego de rede reduzido. Apenas o nome do procedimento é passado.
* Segurança. Pode reduzir as ameaças removendo o acesso direto aos objetos do banco de dados.
* Flexibilidade. Os procedimentos armazenados são facilmente modificados em tempo de execução.

### Desvantagens do stored procedure
* Os procedimentos armazenados podem ser difíceis de depurar.
* Requer pessoal qualificado com experiência em T-SQL.
* Só funciona no SQL Server. Outros fornecedores de banco de dados oferecem suporte a idiomas diferentes.

### Procedimentos Armazenados vs Funções
Uma lista de diferenças entre procedimentos armazenados e funções.

|STORED PROCEDURE|	FUNCTION|
|--|--|
|O valor de retorno é opcional|	Deve retornar um valor|
|Suporta parâmetros de entrada e saída	|Suporta apenas parâmetros de entrada|
|Não pode ser chamado de uma função	|Pode ser chamado a partir de um procedimento|
|Permite consultas SELECT, INSERT, UPDATE e DELETE.	|Permite apenas instruções SELECT|
|Não pode ser utilizado em uma instrução SELECT|	Pode ser incorporado em uma instrução SELECT|
|Suporta exceções Try-Catch|	Não suporta exceção de erro|
|Suporta transações|	Não suporta transações|

### Stored Procedure do sistema
* Cada instalação do SQL Server vem com muitos procedimentos de sistema integrados.
* Esses procedimentos são armazenados no banco de dados 'mestre'.
* Muitos procedimentos do sistema são nomeados com um sp_prefixo (para procedimento armazenado).
* Eles impedem que os usuários modifiquem diretamente os catálogos do sistema e do banco de dados.
* Os desenvolvedores geralmente ignoram esses procedimentos, mas eles são importantes para os administradores.
* Estes são alguns dos procedimentos de sistema comumente usados.

|PROCEDIMENTO|	DESCRIÇÃO|
|--|--|
|sp_monitor|	Fornece estatísticas de tempo de execução sobre a instância SQL.|
|sp_help|	Fornece informações sobre objetos de banco de dados|
|sp_helptext|	Retorna a definição (DDL) de um objeto de banco de dados|
|sp_who2|	Fornece informações sobre usuários, sessões e processos atuais.|
|sp_kill|	Mata uma sessão. Útil em situações de impasse.|
|sp_tables|	Retorna informações sobre tabelas e visualizações|
|sp_depends|	Retorna as dependências de um objeto de banco de dados|
|sp_executesql|	Usado em T-SQL para executar SQL dinâmico. Esteja atento à injeção de SQL.|
|sp_getapplock|	Identifica bloqueios de transações e objetos.|

## SQL STORED PROCEDURES - MYSQL

```sql=
create table professor(cod_prof int auto_increment primary key,
    cod_aluno int, 
    aluno varchar(35), 
    nota1 float, 
    nota2 float, 
    media float
    );
```

![](https://i.imgur.com/yZNiUa5.png)

```sql=
 insert into professor values(1,1,'Luis',10,10,0);
 insert into professor values(2,2,'Belem',6,5,0);
 insert into professor values(3,3,'Antonio',10,10,0);
```
 
![](https://i.imgur.com/kAnJtDE.png)

```sql=
select * from professor;
```

![](https://i.imgur.com/M0GL7FG.png)

Craição de procedure `calcmedia`

```sql=
 delimiter $
 create procedure calcmedia()
 begin
 declare m float;
 select ((nota1+nota2)/2) into m from professor where cod_aluno=1;
 select m "media do aluno1";
 update professor set media=m where cod_aluno=1;
 end;
 $
```
![](https://i.imgur.com/xCArhB9.png)

Volta o delimitador ao original;
```sql=
delimiter ;
```
![](https://i.imgur.com/ddl6nHb.png)

Chamando a procedure `calcmedia`
```sql=
 call calcmedia();
```
![](https://i.imgur.com/NkVNMok.png)

```sql=
desc professor;
```

![](https://i.imgur.com/NpwznAI.png)


```sql=
delimiter $
create procedure calcmedia2(vcod int)
    begin
    declare m float;
    select ((nota1+nota2)/2) into m from professor where cod_aluno=vcod;
    select m "media do aluno";
    update professor set media=m where cod_aluno=vcod;
    end;
    $
delimiter ;
```
![](https://i.imgur.com/nRVZqrR.png)

```sql=
call calcmedia2(6);
```
![](https://i.imgur.com/pfnOuvJ.png)

```sql=
call calcmedia2(4);
```
![](https://i.imgur.com/qteaSS2.png)

```sql=
update professor set media=(nota1+nota2)/2;
```
![](https://i.imgur.com/sA7jeZj.png)

```sql=
select * from professor;
```
![](https://i.imgur.com/z2BNFK4.png)

```sql=
select  avg(nota1) "media nota1", 
        avg(nota2) "media nota2",
        (avg(nota1)+avg(nota2))/2 "media dos bimestres" from professor;
```    
![](https://i.imgur.com/7R3fqK1.png)
    
```sql=
select avg(nota1) "nota1", aluno
    from professor group by (aluno);
```
![](https://i.imgur.com/wJC36RJ.png)

```sql=
select @media:=avg(nota1) from professor;
```
![](https://i.imgur.com/FGb7EjA.png)

```sql=
select @media2:=avg(nota2) from professor;
```
![](https://i.imgur.com/Z0Ubw8e.png)

```sql=
select @mf:=(@media+@media2)/2 "media Final";
```
![](https://i.imgur.com/734Vgxv.png)

```sql= 
select * from professor where media < @mf;
```
![](https://i.imgur.com/58i7F26.png)

```sql= 
 create table temp as select * from professor;
```
![](https://i.imgur.com/diy2X1D.png)

```sql= 
 select * from temp;
```
![](https://i.imgur.com/MHn6SU0.png)

```sql=
delimiter $ 
create trigger gatilho1 before insert 
   on professor 
   for each row 
   begin 
   insert into temp values(NEW.cod_prof,  
                           NEW.cod_aluno,  
                           NEW.aluno,  
                           NEW.nota1,  
                           NEW.nota2, 0);
   end; 
$
```
![](https://i.imgur.com/ZBLD2Q4.png)

```sql= 
delimiter ; 
```
![](https://i.imgur.com/mZorkXP.png)

```sql=
insert into professor values(7,24,'David',4,7,0);
```
![](https://i.imgur.com/ZlVSmGi.png)

```sql=
select * from temp;
```
![](https://i.imgur.com/W92OPQc.png)

```sql=
select * from professor;
```
![](https://i.imgur.com/IpdJ4ch.png)

```sql=
create table pessoa(
    cod int, 
    nome varchar(35), 
    datan date
    );

insert into pessoa values(1,'Luis','1978/10/05');
insert into pessoa values(2,'Belem','1973/01/28');
insert into pessoa values(3,'Thiago','2009/05/10');
```
![](https://i.imgur.com/UcKvpwL.png)

```sql= 
delimiter $
create procedure teste(vcod int)
begin
declare datanasc date;
select datan into datanasc from pessoa where cod=vcod;
    if (sysdate()<datanasc) then
  update pessoa set datan='0000/00/00' where cod=vcod;
 select "ERRO NA DATA";
    else
 select datan "Data nascimento certa" from pessoa where cod=vcod;  
    end if;
end;
$

delimiter ;
```
![](https://i.imgur.com/FALZZTO.png)

```sql=
call teste(3);
```
![](https://i.imgur.com/oIov5kv.png)

```sql=
 select * from pessoa;
```
![](https://i.imgur.com/bL1g3hA.png)

```sql= 
update pessoa set datan='1988/02/10' where cod=3;
```
![](https://i.imgur.com/ISXsk0N.png)

```sql=
create table usuario(
        cod int,
        nome varchar(35), 
        idade int, 
        datanasc date);
```
![](https://i.imgur.com/sSlOL3m.png)


```sql=
delimiter $ 
create trigger gatilho2 before insert
    on usuario
    for each row
    begin
    declare n varchar(35);
     if ((NEW.datanasc < sysdate()) and (NEW.idade<130 and NEW.idade>=0)) then
       set n ='teste';
       else
        update usuario set nome='edson' where cod=NEW.cod;
         end if;
     end;
    $
```
![](https://i.imgur.com/TopG6dO.png)

```sql=
 delimiter ;
```

```sql=
 create table paciente(cod_paciente int primary key,
    nome varchar(35),
    email varchar(35));
```    
![](https://i.imgur.com/avJj08D.png)

```sql=
 create table hospital(cod_hospital int primary key,
    hospital varchar(35),
    localizacao varchar(70));
```    
![](https://i.imgur.com/SLmbOQW.png)
    
```sql=
create table alocacao(cod_alocacao int primary key,
    cod_paciente int,
    cod_hospital int,
    foreign key (cod_paciente) references paciente(cod_paciente),
    foreign key (cod_hospital) references hospital(cod_hospital));
```    
![](https://i.imgur.com/WO3HD4P.png)
    
```sql=
insert into paciente values(1,'Edson','edson@bol.com.br');
insert into paciente values(2,'Belem','belem@bol.com.br');
```
![](https://i.imgur.com/W2tIbDJ.png)

```sql=
insert into hospital values(1001,'Servidores','Rua A');
insert into hospital values(1002,'Door','Rua B');
insert into alocacao values(10,2,1002);
insert into alocacao values(11,1,1001);
```
![](https://i.imgur.com/WQ7IG0c.png)

```sql=
select h.hospital, p.nome from hospital h, paciente p, 
 alocacao a where h.cod_hospital and p.cod_paciente=a.cod_paciente;
```
![](https://i.imgur.com/vMHTcM3.png)

```sql=
select h.hospital, p.nome from hospital h, paciente p, 
 alocacao a where h.cod_hospital and p.cod_paciente=a.cod_paciente;
```
![](https://i.imgur.com/ehYvkOm.png)

```sql=
create table funcionario(cod_funcionario int primary key,
     nome varchar(35),
     email varchar(35),
    projeto varchar(35),
     tempoini date,
     tempofim date,
     datadm date,
     tipo int);
```
![](https://i.imgur.com/U8lurMy.png)

```sql=
insert into funcionario values(1,'Andre','andre@bol','caixa economica',
     '2007/12/10','2008/12/10',null,1);
insert into funcionario values(2,'Thiago','thiago@bol',null,null,null,
     '2007/10/10',2);
insert into funcionario values(3,'David','david@bol',null,null,null,
     '2008/02/05',2);
```

```sql=
select nome,email from funcionario where tipo=2;
```
![](https://i.imgur.com/OpMZsxp.png)

```sql=
 create table funcionario1(cod_funcionario int primary key,
     nome varchar(35),
     email varchar(35)
);
```
![](https://i.imgur.com/4YnxRqG.png)

```sql=
create table temporario(cod_temporario int primary key,
     projeto varchar(35), tempoin date,
     tempofin date,
     foreign key(cod_temporario) references funcionario1(cod_funcionario)
);
```
![](https://i.imgur.com/Rr6Es5M.png)

```sql=
create table permanente (cod_permanente int primary key,
     dataadm date,
     foreign key(cod_permanente) references funcionario1(cod_funcionario)
);
```
![](https://i.imgur.com/1Mtm8mo.png)

```sql=
insert into funcionario1 values(1,'Thiago','thiago@bol');
insert into funcionario1 values(2,'Jose','jose@bol');
insert into temporario values(1,'caixa','2007/12/12','2008/12/12');
insert into permanente values(2,'2008/02/05');
```
```sql=
select f.nome, t.projeto from funcionario1 f, temporario t 
where f.cod_funcionario=t.cod_temporario;
```
![](https://i.imgur.com/hLyuVSa.png)

```sql=
create table curso(cod_curso int primary key,
     curso varchar(35),
     preco float);
```
![](https://i.imgur.com/KOTyJN4.png)

```sql=
insert into curso values(1,'Java',150);
insert into curso values(2,'Java JEE',550);
insert into curso values(3,'Oracle',400);
insert into curso values(4,'Mysql',150);
```

**Sum**, faz a soma de todos os numeros de um determinado campo da tabela
```sql=
select sum(preco) "somatorio" from curso;
``` 
![](https://i.imgur.com/KWaFXrF.png)

**count** + campo traz o total de campos 
```sql=
 select count(*) "quantidade" from curso;
```
![](https://i.imgur.com/by1QvUx.png)

```sql=
select substring(curso,1,4) from curso;
```
![](https://i.imgur.com/cPn391Q.png)

```sql=
select curso from curso;
```
![](https://i.imgur.com/NJ25uBg.png)

Traz somente os campos desejados.
```sql=
select curso, preco from curso where substring(curso,1,4)='Java';
```
![](https://i.imgur.com/evqC4lN.png)

Busca os campos quando preco for 150
```sql=
select curso, preco from curso where preco=150;
```
![](https://i.imgur.com/MckuzVG.png)

###  STORED PROCEDURE 

Faz com que quando der o final de comando, nao use + ; e sim oq foi definido
```sql=
DELIMITER $$
```

```sql=
create procedure totais()
     begin
     select count(*) "Quantidade de cursos" from curso;
     select sum(preco) "somatorio" from curso;
     select count(curso) "contagem", curso from curso group by curso;
     select max(preco) "maior preco" from curso;
     select min(preco) "menor preco" from curso;
     end;
     $$
```
![](https://i.imgur.com/OdQPZ8N.png)

```sql=
delimiter ;
```

```sql=
call totais();
```
![](https://i.imgur.com/fpyjXG3.png)

```sql= 
 insert into curso values(6,'Oracle',1000);
``` 
![](https://i.imgur.com/J5efmii.png)
 
```sql=
call totais();
```
![](https://i.imgur.com/doodSV6.png)

```sql=
select max(preco),curso from curso group by curso
     having curso = 'Oracle';
```     
![](https://i.imgur.com/GAsaj8R.png)

```sql=
create table temporario_curso(cod_curso int primary key,
     curso varchar(30),
     preco float);
```
![](https://i.imgur.com/x8BeafB.png)

```sql=
select * from curso;
```
![](https://i.imgur.com/4MHJpgM.png)

```sql=
insert into temporario_curso select * from curso;
``` 
![](https://i.imgur.com/CvzyIpP.png)

```sql=
select * from temporario_curso;
```
![](https://i.imgur.com/jlL5x0x.png)

```sql=
select found_rows() 'estados';
```
![](https://i.imgur.com/m3ZNPFp.png)

```sql=
create table cliente (
    codcliente int primary key,
    nome varchar(15)
);
``` 
![](https://i.imgur.com/Eewzh8u.png)

```sql=
insert into cliente values (1, "belem");
insert into cliente values (2, "edson");
insert into cliente values (3, "pamela");
```
![](https://i.imgur.com/P6ASXP5.png)

```sql=
create table telefone (codtel int primary key,
     telefone varchar (15),
     cod_cliente int,
     foreign key(cod_cliente) references cliente(codcliente)
);
```
![](https://i.imgur.com/3o5fQpy.png)

```sql=
insert into telefone values (10,'78152836',3);
insert into telefone values (11,'78152807',3);
insert into telefone values (12,'999999',1);
insert into telefone values (13,'888888',1);
insert into telefone values (14,'555555',1);
insert into telefone values (15,'77777',2);
insert into telefone values (16,'333333',2);
```
 ![](https://i.imgur.com/uYAT42T.png)

```sql=
select c.nome,t.telefone from cliente c, telefone t
     where c.codcliente=t.cod_cliente;
```
![](https://i.imgur.com/IZ7aUvS.png)

```sql=
 select c.nome,t.telefone from cliente c  inner join  telefone t where c.codcliente = t.cod_cliente;
```
![](https://i.imgur.com/xqWMDtt.png)

```sql=
drop table funcionario;
```
![](https://i.imgur.com/tWEdU8U.png)

```sql=
create table funcionario (codfuncionario int primary key,
     nome varchar (35),
     dataadmissao date);
```
![](https://i.imgur.com/HSAtnD0.png)

```sql=
insert into funcionario values (1,'thiago aspira','2008/05/25');
```
![](https://i.imgur.com/BtSBo3j.png)

```sql=
 select * from funcionario;
```
![](https://i.imgur.com/2Q7Zs20.png)

```sql=
insert into funcionario (codfuncionario,nome)  values (2,'belem');
```
![](https://i.imgur.com/9OdDN7q.png)

```sql=
select * from funcionario;
```
![](https://i.imgur.com/1U0rNfl.png)

```sql=
insert into funcionario values (3,'David','2007/12/20');
```
![](https://i.imgur.com/rAAVuqr.png)

```sql=
insert into funcionario values (4,'Anthony','2008/04/10');
```
```sql=
select * from funcionario;
```
![](https://i.imgur.com/AWuF0NR.png)

```sql=
select * from funcionario where dataadmissao between '2008/04/01' and '2008/07/05';
```
![](https://i.imgur.com/yy2kAqN.png)

```sql=
set @senha=aes_encrypt('coti','123');
```
![](https://i.imgur.com/NsZ0JSv.png)

```sql=
 select @senha;
```
![](https://i.imgur.com/sS56qny.png)

```sql=
select aes_decrypt(@senha,'123');
```
![](https://i.imgur.com/JVX1fzN.png)





















## SQL STORED PROCEDURES - ORACLE

### PRÁTICAS SQL
Entrando no banco de dados.
* system -- usuário
* coti -- senha
```sql=
conn system/coti
```
![](https://i.imgur.com/bSUliBN.png)

Visualizando onome do banco de dados.
```sql=
 select  name from v$database;
```
![](https://i.imgur.com/0Kru256.png)

Visualizando a versão
```sql=
select banner from V$version;
--VERSÂO
```
![](https://i.imgur.com/mgDA8bR.png)

Visualizando o usuario logado.
```sql=
--toda hora fazer isso
select user from dual;
```
![](https://i.imgur.com/vflk5CI.png)


Comando para criar o usuário `usuarioum` com a senha `coti` no workspace `users` com espaço em disco de `200mb`.
```sql=
create user usuarioum identified by coti 
  default tablespace users 
    quota 200m on users;
--Cria o usuario usuarioum senha coti
--local (tablespace users)
-- espaco de 200m 
```
![](https://i.imgur.com/a2vgw0P.png)

Logando com o novo usuario criado.
```sql=
----Logar como usuarioum
conn usuarioum/coti
---permissao basica
```
![](https://i.imgur.com/G8O6YoI.png)

Criando uma trigger
```sql=
--trigger
grant create table, create procedure, create trigger, 
     create session, create sequence, create view
      to usuarioum;
--criar tabela, (programar,), engatilhar, ao logar, sequence, view
```
![](https://i.imgur.com/qarwsr5.png)

Alterando a sessão para formatar a exibição da data.
```sql=
alter session set nls_date_format='dd/mm/yyyy';
 --resalva alter session set nls_date_format='yyyy-mm-dd';
```
![](https://i.imgur.com/suwY5IN.png)

Visualizando a data do banco.
```sql=
 select sysdate from dual;
```
![](https://i.imgur.com/q4t8jtu.png)

Executando uma soma.
```sql=
 select (10 + 20+ 30)/3 as soma from dual;
```
![](https://i.imgur.com/mWDg9Nn.png)

Conferindo em qual usuario estamos logados.
```sql=
 select user from dual;
 --que usuario eu sou ...
```
![](https://i.imgur.com/VuNBY9k.png)

Criação da tabela `produto` e criação da sequencia de auto numeração da tabela produto `SEQ_PRODUTO`
```sql=
 --dinamica (geralmente) _ id (chaves) _ são sequencias _ (auto_numéricas)
 -- varchar (2000) - varchar2 (4000) (oracle)
  --number (10) _ inteiro 
  -- number (10,2)_ flutuante
  --date --> (timestamp) = eternidade ... ele atua mundialmente (ou seja) 
  --(fuso) ...

  --regra ao lado (Amadoramente)
  create table  produto(idProduto number (10) primary key,
                        nomeProduto  varchar2 (50)  not null,
                        preco number (10,2) default 0,
                        quantidade number (10,2) default 0);

  create sequence SEQ_PRODUTO;
 --(2 detalhes) _ Tabela versus Sequência ....
```
![](https://i.imgur.com/meIvVMO.png)

Mostrar todas as tabelas.
```sql=
 select * from cat;
```
![](https://i.imgur.com/CSmgYjT.png)

Criação ou alteração da procedure `SaveProduto` para que quando grave o produto, insira a sequencia de auto numeração e exiba a mensagem de produto cadastrado, se der errado apresenta o erro na tela.
```sql=
-->procedure (sub-programa) _ entrada (IN) _ sAÍDA (OUT) _ in-OUT 
-- > in (PROCEDURE) NAO RETORNA
--> Comandos para voce (impressao)
--Deve ser Habilitado

set serveroutput on size 10000;

create or replace procedure SaveProduto(
    vnomeProduto in varchar2, 
    vpreco in number, 
    vquantidade in number 
   ) as
   begin
       insert into  produto values (
           SEQ_PRODUTO.nextval, 
           nomeProduto, 
           vpreco, 
           vquantidade);
       commit;
       dbms_output.put_line('Produto Cadastrado'); 
   exception when others then 
      dbms_output.put_line('Error:' || sqlerrm); 
       rollback;
  end;
/
```
![](https://i.imgur.com/uRrRhd3.png)

Executando a procedure, ou seja, pasando os dados para gravação do produto. Foi exibido a mensagem de *produto gravado*.
```sql=
 exec SaveProduto('havaians',100.5,1);
 --produto gravasdo com sucesso
```
![](https://i.imgur.com/qAe0GEq.png)

Formatação da forma com que será exibido os dados.
|comando|descrição|
|--|--|
| column nomeproduto format a15;|formatando a coluna nomeproduto com a largura de 15 caracteres|
 |set linesize 2000;|mostrará até 2000 linhas|
| select * from produto;|lista todos os produtos|
```sql=
 -------Formata antes (antes do select)
 column nomeproduto format a15;
 set linesize 2000;
 
 select * from produto;
```
![](https://i.imgur.com/izcGgLb.png)






## SQL INSERT
* Uma instrução INSERT adiciona uma nova linha a uma tabela.
* INSERT pode conter valores para algumas ou todas as suas colunas.
* INSERT pode ser combinado com um SELECT para inserir registros.

**Exemplo**
Uma instrução INSERT que adiciona um novo fornecedor ao banco de dados.
```sql=
INSERT INTO Supplier (CompanyName, ContactName, 
                      City, Country, Phone)
VALUES ('Broodjes Huis', 'Henk de Groot', 
        'Amsterdam', 'Netherlands', '31-1-382-8847')
```

### Sintaxe

**Exemplo**
Sintaxe INSERT.
```sql=
INSERT INTO nome - da-tabela ( nomes -da - coluna ) 
VALORES ( valores ) 
```

INSERT com sintaxe SELECT.
```sql=
INSERT INTO nome - da-tabela ( nomes -da - coluna ) 
coluna SELECT - nomes
  Tabela FROM - nome
ONDE condição
```

**Exemplo**
`Insert`
Adicionar o novo cliente Craig Smith ao banco de dados.
![](https://i.imgur.com/3tynnem.png)
```sql=
INSERT INTO Customer (FirstName, LastName, City, Country, Phone)
VALUES ('Craig', 'Smith', 'New York', 'USA', '1-01-993 7800')
```
**Exemplo**
`insert select`
O fornecedor da Bigfoot Brewery também se tornou um cliente. Adicione um registro de cliente com valores da tabela de fornecedores.
![](https://i.imgur.com/aWsj9Jj.png)
```sql=
INSERT INTO Customer (FirstName, LastName, City, Country, Phone)
SELECT LEFT(ContactName, CHARINDEX(' ',ContactName) - 1), 
       SUBSTRING(ContactName, CHARINDEX(' ',ContactName) + 1, 100), 
       City, Country, Phone
  FROM Supplier
 WHERE CompanyName = 'Bigfoot Breweries'
```

## SQL SELECT
* SELECT recupera dados de um banco de dados.
* Os dados são retornados em uma estrutura semelhante a uma tabela chamada conjunto de resultados .
* SELECT é a operação mais comumente usada em um banco de dados.

**Exemplo**
Liste todos os fornecedores no Reino Unido.
```sql=
SELECT *
  FROM Supplier
 WHERE Country = 'UK'
```

### Sintaxe
Sintaxe SELECT.
```sql=
coluna SELECT - nomes
  Tabela FROM - nome
```

Para incluir todas as colunas, use *
```sql=
SELECIONE *
  Tabela FROM - nome
```

**Exemplo**
Liste todos os customers.
![](https://i.imgur.com/qbRov3c.png)

```sql=
SELECT * 
  FROM Customer
```

### Selecione com colunas 
Liste o nome, sobrenome e cidade de todos os clientes.
```sql=
SELECT FirstName, LastName, City 
  FROM Customer
```

## SQL WHERE
* A cláusula WHERE filtra os dados que atendem a alguns critérios.
* WHERE retorna apenas as linhas nas quais você está interessado.
* Uma condição WHERE retorna verdadeiro ou falso.

**Exemplo**
Listar todos os fornecedores na França.
```sql=
SELECT *
  FROM Supplier
 WHERE Country = 'France'
```

### Sintaxe
Sintaxe de WHERE em uma instrução SELECT.
```sql=
coluna SELECT - nomes
  Tabela FROM - nome
ONDE condição
```

Sintaxe de WHERE em uma instrução UPDATE.
```sql=
Tabela UPDATE - nome
   Coluna SET - nome = valor
ONDE condição
```

Sintaxe de WHERE em uma instrução DELETE.
```sql=
DELETE tabela - nome
ONDE condição
```

### Selecione where.
**Exemplos**
Liste todos os clientes na Suécia.
```sql=
SELECT Id, FirstName, LastName, City, Country, Phone
  FROM Customer
 WHERE Country = 'Sweden'
 ```

### Atualizar where
Para o fornecedor Pavlova, Ltd, mude a cidade para Sydney.
![](https://i.imgur.com/3mYFZEU.png)
```sql=
UPDATE Supplier
   SET City = 'Sydney'
 WHERE CompanyName = 'Pavlova, Ltd.'
 ```

### Delete where
Exclua produtos com preço superior a US$ 50.
![](https://i.imgur.com/L2KgfOj.png)

```sql=
DELETE FROM Product
 WHERE UnitPrice > 50
```

### Desempenho SQL where
Certifique-se de que as colunas incluídas na cláusula WHERE estejam indexadas corretamente . Caso contrário, é executada uma varredura de tabela , que, com tabelas grandes, pode ser muito lenta.

## SQL UPDATE
* UPDATE altera os valores de dados em um banco de dados.
* UPDATE pode atualizar um ou mais registros em uma tabela.
* Use a cláusula WHERE para atualizar apenas registros específicos.

**Exemplo**
Alterar o número de telefone do fornecedor Tokio Traders.
```sql=
UPDATE Supplier
   SET Phone = '(03) 8888-5011'
 WHERE CompanyName = 'Tokyo Traders'
 ```

### Sintaxe
Sintaxe UPDATE.
```sql=
Tabela UPDATE - nome
   SET coluna - nome1 = valor1 , 
       coluna - nome2 = valor2 , ... 
```

Sintaxe UPDATE com uma cláusula WHERE.
```sql=
Tabela UPDATE - nome
   SET coluna - nome1 = valor1 , 
       coluna - nome2 = valor2 , ... 
ONDE condição
```

**Exemplo**
`update`
Descontinuar todos os produtos no banco de dados.
![](https://i.imgur.com/NrlVw1v.png)
```sql=
UPDATE Product
   SET IsDiscontinued = 1
```

**Exemplo**
`Update where`
Descontinuar todos os produtos acima de $ 50.
```sql=
UPDATE Product
   SET IsDiscontinued = 1
 WHERE UnitPrice > 50
```

**Exemplo**
ATUALIZAR Registro Único.
Descontinuar o produto com Id = 46.
```sql=
UPDATE Product
   SET IsDiscontinued = 1
 WHERE Id = 46
```

**Exemplo**
ATUALIZAR Múltiplas Colunas.
O fornecedor Norske Meierier (Id = 15) foi movido.
Mude sua cidade, telefone e fax com valores atualizados.
```sql=
UPDATE Supplier
   SET City = 'Oslo', 
       Phone = '(0)1-953530', 
       Fax = '(0)1-953555'
 WHERE Id = 15
```

## SQL DELETE
* DELETE exclui permanentemente as linhas de uma tabela.
* DELETE pode excluir um ou mais registros em uma tabela.
* Use a cláusula WHERE para EXCLUIR apenas registros específicos.

**Exemplo**
Remover a cliente Elizabeth Lincoln que mora no Canadá.
```sql=
DELETE Customer
 WHERE FirstName = 'Elizabeth' 
   AND LastName = 'Lincoln'
   AND Country = 'Canada'
```

### Sintaxe
Sintaxe DELETE.
```sql=
DELETE tabela - nome
```

DELETE sintaxe com WHERE.
```sql=
DELETE tabela - nome
ONDE condição
```

**Exemplos**
SQL delete.
Remova todos os produtos.
```sql=
DELETE Product
```

**Exemplo**
SQL delete where.
Remova produtos acima de $ 50.
![](https://i.imgur.com/CRZodgp.png)
```sql=
DELETE Product
 WHERE UnitPrice > 50
```

**Exemplo**
SQL DELETE registro único.
Remova o cliente com Id = 21.
![](https://i.imgur.com/JViQmlw.png)
```sql=
DELETE Customer
 WHERE Id = 21
```

## SQL ORDER BY
* Por padrão, SELECT retorna linhas em nenhuma ordem específica.
* A cláusula ORDER BY retorna as linhas em uma determinada ordem de classificação .
* As linhas podem ser retornadas em ordem de classificação crescente ou decrescente .

**Exemplo**
Liste todos os clientes classificados por país.
```sql=
SELECT * 
  FROM Customer
 ORDER BY Country
```

### Sintaxe
Sintaxe `ORDER BY`.
```sql=
coluna SELECT - nomes
  Tabela FROM - nome
ONDE condição
ORDER BY nomes das colunas [ ASC , DESC ]
```

| column-names | um ou mais nomes de colunas para classificação. |
| -------- | -------- |
|ASC|ordem de classificação crescente: de baixo para cima, de a a z. Este é o padrão.|
|DESC|ordem de classificação decrescente: alto para baixo, z para a.|

**Exemplos**
ORDER BY, ordem crescente.
Liste todos os fornecedores em ordem alfabética.
```sql=
SELECT Id, CompanyName, ContactName, City, Country
  FROM Supplier
 ORDER BY CompanyName
```

**Exemplo**
ORDER BY, ordem decrescente.
Liste todos os fornecedores em ordem alfabética inversa.
![](https://i.imgur.com/pHCUVAx.png)
```sql=
SELECT Id, CompanyName, ContactName, City, Country
  FROM Supplier
 ORDER BY CompanyName DESC
```
*A palavra-chave DESC denota descendente, ou seja, ordem inversa.*

**Exemplo**
ORDER BY, várias colunas
```sql=
SELECT FirstName, LastName, City, Country
  FROM Customer
 ORDER BY Country, City
```

**Exemplo**
ORDER BY, ascendente e descendente.
Liste todos os fornecedores nos EUA, Japão e Alemanha, ordenados por cidade e depois pelo nome da empresa na ordem inversa.
```sql=
SELECT Id, CompanyName, City, Country
  FROM Supplier
 WHERE Country IN ('USA', 'Japan', 'Germany')
 ORDER BY Country ASC, CompanyName DESC
```

**Exemplo**
ORDER BY, com datas.
Liste todos os pedidos, classificados por valor (o maior primeiro), em cada ano.
![](https://i.imgur.com/Avst8fD.png)
```sql=
SELECT Id, OrderDate, CustomerId, TotalAmount
  FROM [Order]
 ORDER BY YEAR(OrderDate) ASC, TotalAmount DESC	
```

## SQL JOIN
* Um JOIN combina registros de duas tabelas.
* JOIN corresponde a valores de coluna relacionados em duas tabelas.
* Uma consulta pode conter zero, uma ou várias operações JOIN.
![](https://i.imgur.com/68Hy5C7.png)

**Exemplo**
Liste todos os fornecedores com seus produtos.
```sql=
SELECT CompanyName, ProductName
  FROM Supplier S
  JOIN Product P ON S.Id = P.SupplierId
```
*S e P na consulta acima são aliases de tabela.*

### Tipos de SQL JOIN

|TIPO	|DESCRIÇÃO|
|---|---|
|JOIN|	Registros de correspondência em ambas as tabelas|
|ASSOCIAÇÃO À ESQUERDA|	Corresponder os registros da tabela esquerda (primeiro) com os registros da tabela direita|
|JUNTAR À DIREITA	|Corresponder os registros da tabela à direita (últimos) com os registros da tabela à esquerda|
|FULL JOIN	|Incluir todos os registros à esquerda e à direita, independentemente de corresponderem ou não|

### Diagrama SQL JOIN
![](https://i.imgur.com/mUG18mn.png)

### Sintaxe
Sintaxe JOIN.
```sql=
coluna SELECT - nomes
  Tabela FROM - nome1
  Tabela JOIN - nome2 ON coluna - nome1 = coluna - nome2
ONDE condição
```

Sintaxe INNER JOIN.
```sql=
coluna SELECT - nomes
  Tabela FROM - nome1
Tabela INNER JOIN - nome2 ON coluna - nome1 = coluna - nome2
ONDE condição
```
*JOIN é o mesmo que INNER JOIN; a palavra-chave INNER é opcional.*
*JOIN (ou INNER JOIN) é o tipo de operação JOIN mais comumente usado.*

**Exemplo**
JOIN com 2 TABELAS.
Liste todos os pedidos com informações do cliente.
![](https://i.imgur.com/ojlVaZb.png)
```sql=
SELECT OrderNumber, TotalAmount, FirstName, LastName, City, Country
  FROM [Order] O
  JOIN Customer C ON C.Id = O.CustomerId
```
*O e C são aliases de tabela .*

**Exemplo**
JOIN com 3 TABELAS
Liste todos os pedidos com nome do produto, quantidade e preço, classificados por número do pedido.
![](https://i.imgur.com/hMDLhv9.png)
```sql=
SELECT O.OrderNumber, CONVERT(date,O.OrderDate) AS Date, 
       P.ProductName, I.Quantity, I.UnitPrice 
  FROM [Order] O 
  JOIN OrderItem I ON O.Id = I.OrderId 
  JOIN Product P ON P.Id = I.ProductId
 ORDER BY O.OrderNumber
```
*Esta consulta executa duas operações JOIN com 3 tabelas. O, I e P são Aliases de tabela . Date é uma coluna Alias.*

## SQL LEFT JOIN
* Um LEFT JOIN executa uma junção começando com a tabela esquerda .
* Em seguida, todos os registros correspondentes da tabela correta serão incluídos.
* Linhas sem correspondência terão valores de coluna NULL.
![](https://i.imgur.com/Rsjl6bf.png)

**Exemplo**
Liste todos os fornecedores e seus produtos, incluindo fornecedores sem produtos.
```sql=
SELECT CompanyName, ProductName
  FROM Supplier S
  LEFT JOIN Product P ON S.Id = P.SupplierId
```

### Syntax
Sintaxe `LEFT JOIN`.
```sql=
coluna SELECT - nomes
  Tabela FROM - nome1
  LEFT JOIN tabela - nome2 ON coluna - nome1 = coluna - nome2
ONDE condição
```

Sintaxe `LEFT OUTER JOIN`.
```sql=
coluna SELECT - nomes
  Tabela FROM - nome1
  LEFT OUTER JOIN tabela - nome2 ON coluna - nome1 = coluna - nome2
ONDE condição
```
*LEFT JOIN e LEFT OUTER JOIN são iguais. A palavra-chave OUTER é opcional.*

**Exemplo**
Exemplo de junção à esquerda.
Liste todos os clientes e o valor total que eles gastaram, independentemente de terem feito algum pedido ou não.
![](https://i.imgur.com/NzrZddl.png)
```sql=
SELECT OrderNumber, TotalAmount, FirstName, LastName, City, Country
  FROM Customer C 
  LEFT JOIN [Order] O ON O.CustomerId = C.Id
 ORDER BY TotalAmount
```

## SQL RIGHT JOIN
* Um RIGHT JOIN realiza uma junção começando com a tabela da direita.
* Em seguida, todos os registros correspondentes da tabela à esquerda serão incluídos.
* Linhas sem correspondência terão valores de coluna NULL.
![](https://i.imgur.com/6cCSoSv.png)

**Exemplo**
Liste todos os produtos que não possuem pedidos.
```sql=
SELECT ProductName
  FROM OrderItem I 
 RIGHT JOIN Product P ON P.Id = I.ProductId
 WHERE I.Id IS NULL
```

### Sintaxe
Sintaxe `RIGHT JOIN`.
```sql=
coluna SELECT - nomes
  Tabela FROM - nome1
RIGHT JOIN tabela - nome2 ON coluna - nome1 = coluna - nome2
ONDE condição
```

Sintaxe `RIGHT OUTER JOIN`.
```sql=
coluna SELECT - nomes
  Tabela FROM - nome1
RIGHT OUTER JOIN tabela - nome2 ON coluna - nome1 = coluna - nome2
ONDE condição
```
*RIGHT JOIN e RIGHT OUTER JOIN são iguais. A palavra-chave OUTER é opcional.*

**Exemplo**
Exemplo de junção à direita.
Liste os clientes que não fizeram pedidos.
![](https://i.imgur.com/eGKYv8g.png)
```sql=
SELECT FirstName, LastName, City, Country, TotalAmount
  FROM [Order] O 
 RIGHT JOIN Customer C ON O.CustomerId = C.Id
 WHERE TotalAmount IS NULL
```

**Exemplo**
RIGHT JOIN, com um JOIN.
Liste todos os clientes -- com ou sem pedidos -- e uma contagem dos pedidos que incluem uma 'caixa de 2kg com Konbu' (produto com Id = 13). Classifique os resultados por número de pedidos.
![](https://i.imgur.com/xsf1Y6T.png)
```sql=
SELECT DISTINCT (C.Id), Firstname, LastName, COUNT(O.Id) AS Orders
  FROM [Order] O  
  JOIN OrderItem I ON O.Id = I.OrderId AND I.ProductId = 13
 RIGHT JOIN Customer C ON C.Id = O.CustomerId
 GROUP BY C.Id, FirstName, LastName
 ORDER BY COUNT(O.Id)
```

## SQL FULL JOIN
* Um FULL JOIN retorna todos os registros de ambas as tabelas.
* Isso inclui registros que não correspondem.
* Linhas sem correspondência terão valores de coluna NULL.
![](https://i.imgur.com/TCtLdZn.png)

**Exemplo**
Liste todos os clientes e suas datas de pedidos, incluindo aqueles sem pedidos.
```sql=
  FROM Customer C
  FULL JOIN [Order] O ON C.Id = O.CustomerId
 ORDER BY O.OrderDate 
```

### Sintaxe
Sintaxe `FULL JOIN`.
```sql=
coluna SELECT - nomes
  Tabela FROM - nome1
  Tabela FULL JOIN - nome2 ON coluna - nome1 = coluna - nome2
ONDE condição
```

Sintaxe `FULL OUTER JOIN`.
```sql=
coluna SELECT - nomes
  Tabela FROM - nome1
  Tabela FULL OUTER JOIN - nome2 ON coluna - nome1 = coluna - nome2
ONDE condição
```
*FULL JOIN e FULL OUTER JOIN são iguais. A palavra-chave OUTER é opcional.*

**Exemplo**
`FULL JOIN`, 2 tabelas.
Combine todos os clientes e fornecedores por país.
![](https://i.imgur.com/X5bWfQX.png)
```sql=
SELECT C.FirstName, C.LastName, C.Country AS CustomerCountry, 
       S.Country AS SupplierCountry, S.CompanyName
  FROM Customer C 
  FULL JOIN Supplier S ON C.Country = S.Country
 ORDER BY C.Country, S.Country
```
*Isso retorna todas as combinações possíveis de fornecedores e clientes. Isso inclui fornecedores sem clientes em seu país e clientes sem fornecedores em seu país, bem como clientes e fornecedores que são do mesmo país.*

## SQL SELF JOIN
* Em um Self JOIN, uma tabela é unida a si mesma .
* Isso pode ser útil ao modelar hierarquias.
* Outro uso é encontrar duplicatas dentro de uma tabela.

**Exemplo**
Combine fornecedores que são do mesmo país.
```sql=
SELECT A.CompanyName AS Company1, B.CompanyName AS Company2, A.Country
  FROM Supplier A
  JOIN Supplier B ON A.Id <> B.Id
   AND A.Country = B.Country 
 ORDER BY A.Country
```
*A e B são aliases de tabela para a mesma tabela Fornecedor. Company1 e Company2 são aliases de coluna.*

### Sintaxe
Sintaxe de `auto JOIN`.
```sql=
coluna SELECT - nomes
  Mesa FROM - nome T1
  Tabela JOIN - nome T2
ONDE condição
```
*T1 e T2 são aliases de tabela diferentes para a mesma tabela.*

**Exemplo**
Auto JOIN.
Combine clientes que são da mesma cidade e país.
![](https://i.imgur.com/j08dgys.png)
```sql=
SELECT B.FirstName AS FirstName1, B.LastName AS LastName1, 
       A.FirstName AS FirstName2, A.LastName AS LastName2, 
       B.City, B.Country
  FROM Customer A
  JOIN Customer B ON A.Id <> B.Id
   AND A.City = B.City 
   AND A.Country = B.Country
 ORDER BY A.Country
```
*A e B são aliases de tabela para a mesma tabela Cliente.*

**Exemplo**
`Auto JOIN`, encontrando DUPLICADOS.
Encontre clientes com o mesmo nome (ou seja, duplicados).
```sql=
SELECT CONCAT(C1.FirstName, ' ', C1.LastName) AS Name, 
       CONCAT(C2.FirstName, ' ', C2.LastName) AS Duplicate
  FROM Customer C1
  JOIN Customer C2 ON C1.Id <> C2.Id
 WHERE C1.FirstName = C2.FirstName
 ORDER BY C1.FirstName
```
*C1 e C2 são aliases de tabela para a mesma tabela Cliente.*

## SQL UPDATE com JOIN
* Uma instrução UPDATE pode incluir operações JOIN .
* Um UPDATE pode conter zero, uma ou várias operações JOIN.
* O UPDATE afeta os registros que atendem às condições do JOIN.
![](https://i.imgur.com/kNlMNBl.png)

**Exemplo**
Aumente o preço unitário em 10% para todos os produtos que já foram vendidos.
```sql=
UPDATE P
   SET P.UnitPrice = P.UnitPrice * 1.1
  FROM Product P
  JOIN OrderItem I ON P.Id = I.ProductId
```

### Sintaxe
Sintaxe `JOIN`.
```sql=
Tabela UPDATE - nome1
   SET coluna - nome1 = valor1 , 
       coluna - nome2 = valor2 , ... 
  Tabela FROM - nome1
  Tabela JOIN - nome2 ON coluna - nome3 = coluna - nome4
ONDE condição
```

Sintaxe `INNER JOIN`.
```sql=
Tabela UPDATE - nome1
   SET coluna - nome1 = valor1 , 
       coluna - nome2 = valor2 , ... 
  Tabela FROM - nome1
Tabela INNER JOIN - nome2 ON coluna - nome3 = coluna - nome4
ONDE condição
```
*JOIN é o mesmo que INNER JOIN; a palavra-chave INNER é opcional. JOIN, ou INNER JOIN, é o tipo de operação JOIN mais comumente usado.*

**Exemplo**
ATUALIZAR com LEFT JOIN.
Descontinuar produtos que não foram vendidos.
![](https://i.imgur.com/BqSXk8f.png)
```sql=
UPDATE P
   SET IsDiscontinued = 1
  FROM Product P
  LEFT JOIN OrderItem I ON P.Id = I.ProductId
 WHERE I.Id IS NULL
```

**Exemplo**
ATUALIZAÇÃO com 3 JOINs.
Para o cliente Paul Henriot, altere o preço unitário para $ 25 para Queso Calibres em seu pedido.
![](https://i.imgur.com/TKmT8z4.png)
```sql=
UPDATE I
   SET I.UnitPrice = 25
  FROM Customer C
  JOIN [Order] O ON O.CustomerId = C.Id
  JOIN OrderItem I ON O.Id = I.OrderId 
  JOIN Product P ON P.Id = I.ProductId
 WHERE C.FirstName = 'Paul' AND C.LastName = 'Henriot'
   AND P.ProductName = 'Queso Cabrales'
```
*Este UPDATE realiza 3 JOINs com 4 tabelas. C, O, I e P são aliases de tabela .*

## SQL DELETE com JOIN
* Uma instrução DELETE pode incluir operações JOIN .
* Ele pode conter zero, uma ou várias operações JOIN.
* O DELETE remove os registros que atendem às condições do JOIN.
![](https://i.imgur.com/xmGBKHq.png)

**Exemplo**
Remova os produtos que não foram vendidos.
```sql=
DELETE P
  FROM Product P
  LEFT JOIN OrderItem I ON P.Id = I.ProductId
 WHERE I.Id IS NULL
```
*Este problema requer um LEFT JOIN. P e I são aliases de tabela.*

### Sintaxe
Sintaxe `JOIN`
```sql=
DELETE tabela - nome1
  Tabela FROM - nome1
  Tabela JOIN - nome2 ON coluna - nome3 = coluna - nome4
ONDE condição
```

Sintaxe `INNER JOIN`.
```sql=
DELETE tabela - nome1
  Tabela FROM - nome1
Tabela INNER JOIN - nome2 ON coluna - nome3 = coluna - nome4
ONDE condição
```
*JOIN é o mesmo que INNER JOIN; a palavra-chave INNER é opcional.*

**Exemplo**
APAGAR com JOIN.
Para o pedido número 542379, remova o Tofu.
![](https://i.imgur.com/BqSXk8f.png)
```sql=
DELETE OrderItem
  FROM OrderItem
  JOIN [Order] on OrderItem.OrderId = [Order].Id
  JOIN Product ON Product.Id = OrderItem.ProductId
 WHERE OrderNumber = '542379' 
   AND ProductName = 'Tofu'
```
*isso remove um único item do pedido. Com isso, o valor TotalAmount na tabela Order agora é inválido. Para recalcular esse valor, é necessária uma consulta UPDATE separada.*

## SQL SUBQUERY
* Uma Subconsulta é uma consulta dentro de uma consulta .
* As subconsultas fornecem dados para a consulta envolvente.
* As subconsultas podem retornar valores individuais ou uma lista de registros.
* Subconsultas devem ser colocadas entre colchetes ().

**Exemplo**
Liste todos os fornecedores com o número de produtos que eles oferecem.
```sql=
SELECT CompanyName, 
       ProductCount = (SELECT COUNT(P.id)
                         FROM [Product] P
                        WHERE P.SupplierId = S.Id)
  FROM Supplier S
```
*O SELECT aninhado entre colchetes é a Subconsulta.*

### Sintaxe
Não há sintaxe geral. Subconsultas são consultas regulares colocadas entre parênteses. As subconsultas podem ser usadas de maneiras diferentes e em locais diferentes dentro de uma consulta. Uma subconsulta com o operador IN.
```sql=
coluna SELECT - nomes
  Tabela FROM - nome1
WHERE valor IN ( coluna SELECT - nome
                   Tabela FROM - nome2
                  ONDE condição )
```

As subconsultas também podem atribuir valores de coluna a cada registro.
```sql=
SELECT coluna1 = ( SELECT coluna - nome 
                    Tabela FROM - nome
                   ONDE condição ),
       coluna - nomes
  Tabela FROM - nome
ONDE condição
```

**Exemplo**
Subconsulta com IN.
Listar produtos com quantidades de pedidos maiores que 100.
![](https://i.imgur.com/BqSXk8f.png)
```sql=
SELECT ProductName
  FROM Product
 WHERE Id IN (SELECT ProductId
                FROM OrderItem
               WHERE Quantity > 100)
```

**Exemplo**
Subconsulta atribuindo valor de coluna.
Liste todos os clientes com o número total de pedidos.
![](https://i.imgur.com/O2n1tNs.png)
```sql=
SELECT FirstName, LastName,
       OrderCount = (SELECT COUNT(O.id)
                       FROM [Order] O
                      WHERE O.CustomerId = C.Id)
  FROM Customer C
```
*Isso é chamado de subconsulta correlacionada porque a subconsulta faz referência à consulta anexa, especificamente, o C.Id na cláusula WHERE.*

## SQL SELECT TOP
* Uma instrução SELECT TOP n retorna as primeiras n linhas .
* SELECT TOP é útil ao trabalhar com grandes conjuntos de dados.
* Outros bancos de dados usam palavras-chave como LIMIT, OFFSET e ROWNUM.

**Exemplo**
Liste os 5 maiores pedidos, classificados por valor.
```sql=
SELECT TOP 5 *
  FROM [Order]
 ORDER BY TotalAmount DESC
```

### Sintaxe
Sintaxe `TOP`.
```sql=
SELECT TOP n coluna - nomes
  Tabela FROM - nome
```

**Exemplo**
SELECIONE OS 10 MELHORES.
Liste os 10 produtos mais caros classificados por preço.
![](https://i.imgur.com/CRZodgp.png)
```sql=
SELECT TOP 10 Id, ProductName, UnitPrice, Package
  FROM Product
 ORDER BY UnitPrice DESC
```

## SQL SELECT INTO
* SELECT INTO copia dados de uma tabela para uma nova tabela.
* SELECT INTO cria uma nova tabela localizada no grupo de arquivos padrão.

**Exemplo**
Copie produtos que custam mais de US$ 75 para uma nova tabela LuxeProduct.
```sql=
SELECT * 
  INTO LuxeProduct
  FROM Product
 WHERE UnitPrice > 75
```
Em seguida, execute esta consulta:
```sql=
SELECIONE * DE LuxeProduct
```
### Sintaxe
Sintaxe `SELECT INTO`.
```sql=
coluna SELECT - nomes
  INTO novo - tabela - nome
  Tabela FROM - nome
ONDE condição
```

**Exemplo**
`SELECT INTO`.
Copiar fornecedores dos EUA para uma nova tabela SupplierUSA.
```sql=
SELECT Id, CompanyName, ContactName, 
       City, Phone 
  INTO SupplierUSA
  FROM Supplier
 WHERE Country = 'USA'
 ```

## SQL OFFSET-FETCH
* OFFSET exclui o primeiro conjunto de linhas em um conjunto de resultados.
* OFFSET só pode ser usado com uma cláusula ORDER BY.
* OFFSET com FETCH NEXT retorna uma janela definida de linhas.
* OFFSET com FETCH NEXT é ótimo para suporte de paginação .

**Exemplo**
Liste todos, exceto 10 dos maiores pedidos, classificados por valor.
```sql=
SELECT *
  FROM [Order]
 ORDER BY TotalAmount DESC
OFFSET 10 ROWS
```

### Sintaxe
Sintaxe `ORDER BY OFFSET` -- exclui os primeiros n registros.
```sql=
coluna SELECT - nomes
  Tabela FROM - nome
coluna ORDER BY - nomes
DESLOC n LINHAS
```

Sintaxe `ORDER BY OFFSET` -- exclui os primeiros n registros e retorna apenas os próximos m registros.
```sql=
coluna SELECT - nomes
  Tabela FROM - nome
coluna ORDER BY - nomes
DESLOC n LINHAS
BUSCAR AS PRÓXIMAS LINHAS APENAS
```
*Isso retorna apenas registros (n + 1) a (n + m). Veja o exemplo abaixo.*

**Exemplo**
DESLOC n LINHAS.
Liste todos, menos os 10 dos produtos mais caros, classificados por preço.
```sql=
SELECT Id, ProductName, UnitPrice, Package
  FROM Product
 ORDER BY UnitPrice DESC
OFFSET 10 ROWS
```

**Exemplo**
OFFSET n LINHAS, BUSCAR PRÓXIMO
 Liste do 10º ao 15º produtos mais caros classificados por preço.
```sql=
SELECT Id, ProductName, UnitPrice, Package
  FROM Product
 ORDER BY UnitPrice DESC
OFFSET 10 ROWS
 FETCH NEXT 5 ROWS ONLY
```

## SQL SELECT DISTINCT
* SELECT DISTINCT retorna apenas valores exclusivos (sem duplicatas).
* DISTINCT opera em uma única coluna .
* DISTINCT pode ser usado com agregados: COUNT , AVG , MAX , etc.

**Exemplo**
Liste todas as cidades clientes francesas (sem duplicatas).
```sql=
SELECT DISTINCT City
  FROM Customer
 WHERE Country = 'France'
```

### Sintaxe
Sintaxe `DISTINCT`.
```sql=
Coluna SELECT DISTINCT - nome
  Tabela FROM - nome
```

Sintaxe DISTINCT com COUNT ou outros agregados.
```sql=
SELECT COUNT ( nome da coluna DISTINCT )
  Tabela FROM - nome
```

**Exemplo**
`SELECT DISTINCT`
Liste todos os países fornecedores exclusivos em ordem alfabética.
```sql=
SELECT DISTINCT Country
  FROM Supplier
ORDER BY COUNTRY
```

**Exemplo**
SELECT DISTINCT, com COUNT.
Encontre o número de países fornecedores exclusivos.
```sql=
SELECT COUNT (DISTINCT Country) AS Number
  FROM Supplier
```

## SQL SELECT MIN, MAX
* SELECT MIN retorna o menor valor para uma coluna.
* SELECT MAX retorna o maior valor para uma coluna.
* MIN e MAX são funções internas

**Exemplo**
Encontre o maior valor do pedido.
```sql=
SELECT MAX(TotalAmount) AS 'Largest Amount'
  FROM [Order]
```

### Sintaxe
Sintaxe `MIN.`
```sql=
SELECT MIN ( nome da coluna )
  Tabela FROM - nome
```

Sintaxe `MAX`.
```sql=
SELECT MAX ( nome da coluna )
  Tabela FROM - nome
```

**Exemplo**
`SELECT MIN`.
Encontre o produto mais barato.
```sql=
SELECT MIN(UnitPrice) AS 'Cheapest Price'
  FROM Product
```

**Exemplo**
`SELECT MAX`.
Encontre o maior pedido feito em 2014.
```sql=
SELECT MAX(TotalAmount) AS 'Largest Order'
  FROM [Order]
 WHERE YEAR(OrderDate) = 2014
```

**Exemplo**
SELECIONE A DATA MÁXIMA.
Encontre a data do último pedido em 2013.
```sql=
SELECT MAX(OrderDate) AS 'Last Order Date'
  FROM [Order]
 WHERE YEAR(OrderDate) = 2013
```

## SQL SELECT COUNT, SUM e AVG
* COUNT, SUM e AVG são funções agregadas .
* COUNT retorna uma contagem do número de valores de dados.
* SUM retorna a soma dos valores dos dados.
* AVG retorna a média dos valores de dados.

**Exemplo**
Obtenha o número total de produtos.
```sql=
SELECT COUNT(Id) AS 'Product Count'
  FROM Product
```

### Sintaxe
Sintaxe `COUNT`.
```sql=
SELECT COUNT ( nome da coluna )
  Tabela FROM - nome
```

Sintaxe SOMA.
```sql=
SELECT SUM ( nome da coluna )
  Tabela FROM - nome
```

Sintaxe do AVG.
```sql=
SELECT AVG ( nome da coluna )
  Tabela FROM - nome
```

**Exemplo**
SELECIONE A CONTAGEM.
 Obter o número total de clientes.    
![](https://i.imgur.com/j08dgys.png)
```sql=
SELECT COUNT(Id) AS 'Customer Count'
  FROM Customer
```

**Exemplo**
SELECIONE A SOMA.
Calcule o total de vendas em 2013.
![](https://i.imgur.com/Avst8fD.png)
```sql=
SELECT SUM(TotalAmount) AS 'Total Sales'
  FROM [Order]
 WHERE YEAR(OrderDate) = 2013
```

**Exemplo**
SELECIONE MÉDIA.
Calcule o tamanho médio de todos os pedidos.
```sql=
SELECT AVG(TotalAmount) AS 'Avg Order'
  FROM [Order]
```

## SQL WHERE with AND, OR, NOT
* As condições WHERE podem ser combinadas com AND, OR e NOT.
* Essas condições lógicas sempre retornam verdadeiro ou falso.
* Um WHERE com AND requer que duas condições sejam verdadeiras.
* Um WHERE com OR requer que uma das duas condições seja verdadeira.
* Um WHERE com NOT nega a condição especificada.

**Exemplo**
Listar todos os fornecedores em Paris, França.
```sql=
SELECT CompanyName, ContactName, City, Country, Phone, Fax
  FROM Supplier
 WHERE Country = 'France' AND City = 'Paris'
```

### Sintaxe
Cláusula WHERE com AND.
```sql=
coluna SELECT - nomes
  Tabela FROM - nome
ONDE condição1 E condição2
```

Cláusula WHERE com OR.
```sql=
Tabela UPDATE - nome
   Coluna SET - nome = valor
ONDE condição1 OU condição2
```

Cláusula WHERE com NOT.
```sql=
DELETE tabela - nome
ONDE NÃO condição
```

**Exemplo**
WHERE com AND.
Obtenha o cliente chamado Thomas Hardy.
![](https://i.imgur.com/j08dgys.png)
```sql=
SELECT Id, FirstName, LastName, City, Country
  FROM Customer
 WHERE FirstName = 'Thomas' AND LastName = 'Hardy'
``` 

**Exemplo**
WHERE com OR.
Liste todos os clientes da Espanha ou da França.
```sql=
SELECT Id, FirstName, LastName, City, Country
  FROM Customer
 WHERE Country = 'Spain' OR Country = 'France'
```

**Exemplo**
WHERE com NOT.
Liste todos os clientes que não são dos EUA.
```sql=
SELECT Id, FirstName, LastName, City, Country
  FROM Customer
 WHERE NOT Country = 'USA'
```

**Exemplo**
WHERE com NOT, AND.
Liste todos os pedidos que não estejam entre US$ 50 e US$ 15.000.
![](https://i.imgur.com/Avst8fD.png)
```sql=
SELECT Id, OrderDate, CustomerId, TotalAmount
  FROM [Order]
 WHERE NOT (TotalAmount >= 50 AND TotalAmount <= 15000)
 ORDER BY TotalAmount DESC
```

## SQL CASE
* Uma expressão CASE manipula a lógica condicional dentro de uma consulta.
* CASE retorna um valor baseado em uma condição especificada.
* Lógica abrangente pode ser construída com CASE, WHEN, THEN e ELSE.
* CASE pode ser usado com SELECT, UPDATE, WHERE, ORDER BY e HAVING.

**Exemplo**
Liste a disponibilidade de todos os produtos.
```sql=
SELECT ProductName AS Product,
       CASE IsDiscontinued
         WHEN 0 THEN 'Available'
         WHEN 1 THEN 'Not Available'
         ELSE 'Invalid'
       END AS Availability
  FROM Product
```

### Sintaxe
Existem dois formatos CASE diferentes: simples e pesquisado. 

* Sintaxe para o formato CASE simples.
```sql=
CASE input_expression
QUANDO quando_expressão1 ENTÃO resultado_expressão1
QUANDO quando_expressão2 ENTÃO resultado_expressão2
 ...
 [ ELSE else_result_expression ] 
END
```
*As expressões quando são avaliadas em relação à expressão de entrada.*

* Sintaxe para o formato CASE pesquisado .
```sql=
CASE
WHEN if_expression1 THEN result_expression1
WHEN if_expression2 THEN result_expression2
 ...
 [ ELSE else_result_expression ] 
END
```
*As expressões if são expressões lógicas arbitrárias. As instruções CASE podem ter qualquer número de expressões WHEN. ELSE é opcional.*

**Exemplo**
CASE, formato SIMPLES.
Liste os fornecedores e o idioma que eles falam.
![](https://i.imgur.com/pHCUVAx.png)
```sql=
SELECT CompanyName, Country,
       CASE Country
         WHEN 'Australia' THEN 'English'
         WHEN 'Brazil' THEN 'Portuguese'
         WHEN 'Canada' THEN 'English'
         WHEN 'Denmark' THEN 'Danish'
         WHEN 'Finland' THEN 'Finnish'
         WHEN 'France' THEN 'French'
         WHEN 'Germany' THEN 'German'
         WHEN 'Italy' THEN 'Italian'
         WHEN 'Japan' THEN 'Japanese'
         WHEN 'Netherlands' THEN 'Dutch'
         WHEN 'Norway' THEN 'Norwegian'
         WHEN 'Singapore' THEN 'English'
         WHEN 'Spain' THEN 'Spanish'
         WHEN 'Sweden' THEN 'Swedish'
         WHEN 'UK' THEN 'English'
         WHEN 'USA' THEN 'English'
       END AS Language
  FROM Supplier
```

**Exemplo**
CASE, formato PESQUISADO.
![](https://i.imgur.com/CRZodgp.png)
```sql=
 SELECT ProductName, UnitPrice,
        CASE
          WHEN UnitPrice > 50 THEN 'Expensive'
          WHEN UnitPrice > 20 AND UnitPrice <= 50 THEN 'Medium'
          WHEN UnitPrice > 0 AND UnitPrice <= 20 THEN 'Cheap'
          ELSE 'N/a'
        END AS 'Price Category'
  FROM Product
 ORDER BY ProductName
```

## SQL WHERE BETWEEN
* WHERE BETWEEN retorna valores dentro de um determinado intervalo .
* BETWEEN é uma abreviação para >= AND <=.
* BETWEEN é inclusivo, ou seja, os valores inicial e final são incluídos.

**Exemplo**
Liste todos os pedidos entre US$ 1.000 e US$ 2.000.
```sql=
SELECT OrderDate, OrderNumber, TotalAmount
  FROM [Order]
 WHERE TotalAmount BETWEEN 1000 AND 2000
```

### Sintaxe
Sintaxe WHERE BETWEEN.
```sql=
coluna SELECT - nomes
  Tabela FROM - nome
WHERE coluna - nome ENTRE valor1 E valor2
```

**Exemplo**
`WHERE BETWEEN`.
Liste todos os produtos entre US$ 10 e US$ 20, classificados por preço.
![](https://i.imgur.com/CRZodgp.png)
```sql=
SELECT Id, ProductName, UnitPrice
  FROM Product
 WHERE UnitPrice BETWEEN 10 AND 20
 ORDER BY UnitPrice
```

**Exemplo**
SQL WHERE NOT BETWEEN.
Liste todos os produtos que não estejam entre US$ 5 e US$ 100, classificados por preço.
![](https://i.imgur.com/CRZodgp.png)
```sql=
SELECT Id, ProductName, UnitPrice
  FROM Product
 WHERE UnitPrice NOT BETWEEN 5 AND 100
 ORDER BY UnitPrice
```

**Exemplo**
SQL WHERE ENTRE Datas.
obtenha o número de pedidos e o valor total vendido entre 1º de janeiro de 2013 e 31 de janeiro de 2013.
![](https://i.imgur.com/CRZodgp.png)
```sql=
SELECT COUNT(Id) AS Count, 
       SUM(TotalAmount) AS 'Total Sales'
  FROM [Order]
 WHERE OrderDate BETWEEN '1/1/2013' AND '1/31/2013'
```

## SQL WHERE IN
* WHERE IN retorna valores que correspondem aos valores em uma lista .
* Essa lista é codificada permanentemente ou gerada por uma subconsulta.
* WHERE IN é um atalho para várias condições OR.

**Exemplo**
Liste todos os clientes de Londres ou Paris.
```sql=
SELECT *
  FROM Customer
 WHERE City IN ('Paris','London')
```

### Sintaxe
Sintaxe WHERE IN.
```sql=
coluna SELECT - nomes
  Tabela FROM - nome
WHERE nome da coluna IN ( valores ) 
```

**Exemplo**
`WHERE IN`.
Liste todos os fornecedores dos EUA, Reino Unido ou Japão.
![](https://i.imgur.com/CRZodgp.png)
```sql=
SELECT Id, CompanyName, City, Country
  FROM Supplier
 WHERE Country IN ('USA', 'UK', 'Japan')
```

**Exemplo**
`WHERE NOT IN`.
Liste todos os produtos que não custam $ 10, $ 20, $ 30, $ 40 ou $ 50.
```sql=
SELECT Id, ProductName, UnitPrice
  FROM Product
 WHERE UnitPrice NOT IN (10,20,30,40,50)
```

**Exemplo**
WHERE IN Subconsulta.
Liste todos os clientes que são dos mesmos países onde estão os fornecedores.
![](https://i.imgur.com/X5bWfQX.png)
```sql= 
SELECT Id, FirstName, LastName, Country
  FROM Customer
 WHERE Country IN 
       (SELECT Country 
          FROM Supplier) 
```

## SQL WHERE LIKE
* WHERE LIKE determina se uma string corresponde a um padrão.
* WHERE LIKE oferece suporte a duas opções curinga : %e _.
* Use WHERE LIKE quando apenas um fragmento de um valor de texto for conhecido.

**Exemplo**
Liste todos os produtos que são embalados em frascos.
```sql=
SELECT *
  FROM Product
 WHERE Package LIKE '%jars%'
```

### Sintaxe
Sintaxe LIKE.

```sql=
coluna SELECT - nomes
  Tabela FROM - nome
coluna WHERE - nome LIKE valor
```
*Os caracteres curinga permitidos valuesão %(porcentagem) e _(sublinhado).*
* *%(porcentagem) corresponde a qualquer string com zero ou mais caracteres.*
* *_(sublinhado) corresponde a qualquer caractere único.*

**Exemplo**
`WHERE LIKE %`
Liste todos os produtos com nomes que começam com 'Ca'.
![](https://i.imgur.com/CRZodgp.png)
```sql= 
SELECT Id, ProductName, UnitPrice, Package
  FROM Product
 WHERE ProductName LIKE 'Ca%'
```

**Exemplo**
`WHERE LIKE _`
Liste todos os produtos que começam com 'Cha' ou 'Chan' e possuem mais um caractere.
```sql=
SELECT Id, ProductName, UnitPrice, Package
  FROM Product
 WHERE ProductName LIKE 'Cha_' OR ProductName LIKE 'Chan_'
```

## SQL IS NULL
* WHERE IS NULL testa se uma coluna tem um valor NULL .
* NULL é um valor especial que significa desconhecido ou nenhum valor .
* O teste de NULL com o operador = não é possível .

**Exemplo**
Liste os clientes que não fizeram nenhum pedido.
```sql=
SELECT C.Id, FirstName, LastName, TotalAmount
  FROM Customer C
  LEFT JOIN [Order] O ON C.Id = O.CustomerId
 WHERE TotalAmount IS NULL
```

### Sintaxe
É a sintaxe NULL.
```sql=
coluna SELECT - nomes
  Tabela FROM - nome
coluna WHERE - nome IS NULL
```

É a sintaxe NOT NULL.
```sql=
coluna SELECT - nomes
  Tabela FROM - nome
WHERE coluna - nome NÃO É NULO
```

**Exemplo**
Is null.
Liste todos os fornecedores que não possuem fax.
![](https://i.imgur.com/pHCUVAx.png)
```sql= 
SELECT Id, CompanyName, Phone, Fax 
  FROM Supplier
 WHERE Fax IS NULL
```

**Exemplo**
Not is null.
Liste todos os fornecedores com um fax.
```sql=
SELECT Id, CompanyName, Phone, Fax 
  FROM Supplier
 WHERE Fax IS NOT NULL
```

## SQL GROUP BY
* A cláusula GROUP BY agrupa registros em linhas de resumo.
* GROUP BY retorna um registro para cada grupo.
* GROUP BY é usado com agregados: COUNT , MAX , SUM , etc.

**Exemplo**
Liste o número de produtos para cada fornecedor, classificados de cima para baixo.
```sql=
SELECT S.CompanyName, COUNT(P.Id) AS Products 
  FROM Supplier S
  JOIN Product P ON S.Id = P.SupplierId
 GROUP BY S.CompanyName
 ORDER BY COUNT(P.Id) DESC
```

### Sintaxe
Sintaxe GROUP BY.
```sql=
coluna SELECT - nomes
  Tabela FROM - nome
ONDE condição
coluna GROUP BY - nomes
```

Sintaxe GROUP BY com ORDER BY.
```sql=
coluna SELECT - nomes
  Tabela FROM - nome
ONDE condição
coluna GROUP BY - nomes
coluna ORDER BY - nomes
```

**Exemplo**
GROUP BY com COUNT.
Liste o número de clientes em cada país.
![](https://i.imgur.com/j08dgys.png)
```sql= 
SELECT Country, COUNT(Id) AS Customers
  FROM Customer
 GROUP BY Country
```

**Exemplo**
GROUP BY com COUNT, ORDER BY
Liste o número de clientes em cada país, classificados de cima para baixo.
```sql= 
SELECT Country, COUNT(Id) AS Customers 
  FROM Customer
 GROUP BY Country
 ORDER BY COUNT(Id) DESC
```

**Exemplo**
GROUP BY com SUM, ORDER BY.
 Liste o valor total do pedido para cada cliente, classificado de cima para baixo.
![](https://i.imgur.com/ojlVaZb.png)
```sql=
SELECT C.FirstName, C.LastName, 
       SUM(O.TotalAmount) AS Total 
  FROM [Order] O 
  JOIN Customer C ON O.CustomerId = C.Id
 GROUP BY C.FirstName, C.LastName
 ORDER BY SUM(O.TotalAmount) DESC
```

## SQL HAVING
* HAVING é como WHERE, mas opera em registros agrupados .
* HAVING requer que uma cláusula GROUP BY esteja presente.
* Os grupos que atenderem aos critérios HAVING serão devolvidos.
* HAVING é usado com agregados: COUNT , MAX , SUM , etc.

**Exemplo**
Liste todos os países com mais de 2 fornecedores.
```sql=
SELECT Country, COUNT(Id) AS Suppliers
  FROM Supplier
 GROUP BY Country
HAVING COUNT(Id) > 2
```

### Sintaxe
TENDO sintaxe.
```sql= 
coluna SELECT - nomes
  Tabela FROM - nome
ONDE condição
coluna GROUP BY - nomes
TENDO condição
```

Sintaxe HAVING com ORDER BY.
```sql=
coluna SELECT - nomes
  Tabela FROM - nome
ONDE condição
coluna GROUP BY - nomes
TENDO condição
coluna ORDER BY - nomes
```

**Exemplo**
HAVING com COUNT
Liste o número de clientes em cada país. Incluir apenas países com mais de 10 clientes.
![](https://i.imgur.com/j08dgys.png)
```sql=
SELECT Country, COUNT(Id) AS Customers
  FROM Customer
 GROUP BY Country
HAVING COUNT(Id) > 10
```

**Exemplo**
HAVING e ORDER BY
Liste o número de clientes em cada país, exceto os EUA, classificados de cima para baixo. Incluir apenas países com 9 ou mais clientes.
```sql=
SELECT Country, COUNT(Id) AS Customers
  FROM Customer
 WHERE Country <> 'USA'
 GROUP BY Country
HAVING COUNT(Id) >= 9
 ORDER BY COUNT(Id) DESC
```

**Exemplo**
HAVING with AVG BETWEEN.
Liste clientes com pedidos médios entre US$ 1.000 e US$ 1.200.
![](https://i.imgur.com/ojlVaZb.png)
```sql=
SELECT FirstName, LastName, 
       CONVERT(DECIMAL(10,2), AVG(TotalAmount)) AS 'Average  Order'
  FROM [Order] O 
  JOIN Customer C ON O.CustomerId = C.Id
 GROUP BY FirstName, LastName
HAVING AVG(TotalAmount) BETWEEN 1000 AND 1200
```

## SQL UNION
* UNION combina os conjuntos de resultados de duas consultas SELECT.
* O tipo de dados e a ordem das colunas nessas consultas devem corresponder.
* SQL UNION retorna apenas linhas exclusivas.
* SQL UNION ALL permite a presença de linhas duplicadas.
![](https://i.imgur.com/oGmPGDH.png)

**Exemplo**
Liste todos os contatos (clientes e fornecedores) e seus números de telefone, classificados por país.
```sql=
SELECT FirstName + ' ' + LastName AS Contact, Phone, Country
  FROM Customer
UNION
SELECT ContactName, Phone, Country
  FROM Supplier
 ORDER BY Country
```
 
### Sintaxe
Sintaxe UNIÃO.
```sql=
coluna SELECT - nomes1
  Tabela FROM - nome1
UNIÃO
coluna SELECT - nomes2
  Tabela FROM - nome2
```

Sintaxe UNION ALL.
```sql=
coluna SELECT - nomes1
  Tabela FROM - nome1
UNIÃO TODOS
coluna SELECT - nomes2
  Tabela FROM - nome2 
``` 
 
**Exemplo**
UNION SQL
Liste todos os países exclusivos para clientes e fornecedores.
![](https://i.imgur.com/X5bWfQX.png)
```sql= 
SELECT Country
  FROM Customer
UNION
SELECT Country
  FROM Supplier
```

**Exemplo**
UNION ALL
Liste todos os países para clientes e fornecedores, incluindo duplicados, classificados por país.
```sql=
SELECT Country
  FROM Customer
UNION ALL
SELECT Country
  FROM Supplier
 ORDER BY Country
```
 
**Exemplo**
UNION Múltiplas Colunas
Liste todos os contatos com detalhes completos, tanto clientes quanto fornecedores.
```sql=
SELECT 'Customer' As Type, 
       FirstName + ' ' + LastName AS ContactName, 
       City, Country, Phone
  FROM Customer
UNION
SELECT 'Supplier', 
       ContactName, City, Country, Phone
  FROM Supplier
```

## SQL INTERSECT
* INTERSECT combina os resultados de duas consultas SELECT.
* INTERSECT retorna apenas linhas idênticas das duas consultas.
* O tipo de dados e a ordem das colunas nas duas consultas devem corresponder.
![](https://i.imgur.com/fIJbl8u.png)

**Exemplo**
Liste clientes e fornecedores que compartilham o mesmo nome.
```sql=
SELECT FirstName 
  FROM Customer
INTERSECT
SELECT LEFT(ContactName, CHARINDEX(' ', ContactName) - 1) 
  FROM Supplier
``` 

### Sintaxe
Sintaxe INTERSECT.
```sql=
coluna SELECT - nomes
  Tabela FROM - nome1
INTERSECÇÃO
coluna SELECT - nomes
  Tabela FROM - nome1
```

**Exemplo**
SELECIONE A INTERSEÇÃO
Liste todos os clientes de Portland, EUA.
![](https://i.imgur.com/j08dgys.png)
```sql=
SELECT FirstName, LastName, 
       City, Country 
  FROM Customer    
 WHERE City = 'Portland'
INTERSECT   
SELECT FirstName, LastName, 
       City, Country 
  FROM Customer    
 WHERE Country = 'USA'
```

Claramente, a consulta a seguir é mais eficaz:
```sql= 
SELECT FirstName , LastName , City , Country 
  FROM Customer  
 WHERE City = 'Portland' AND Country = 'USA' 
```

## SQL EXCEPT
* EXCEPT combina os resultados de duas consultas SELECT.
* EXCEPT retorna linhas da primeira consulta que não estão na segunda consulta.
* O tipo de dados e a ordem das colunas nas duas consultas devem corresponder.
![](https://i.imgur.com/6GgWktd.png)

**Exemplo**
Liste todos os produtos com um preço inferior a US$ 10.
```sql=
SELECT Id, ProductName, UnitPrice
  FROM Product
EXCEPT
SELECT Id, ProductName, UnitPrice
  FROM Product
 WHERE UnitPrice >= 10
```

### Sintaxe
EXCETO sintaxe.
```sql=
coluna SELECT - nomes
  Tabela FROM - nome1
EXCETO
coluna SELECT - nomes
  Tabela FROM - nome1
```

**Exemplo**
EXCETO, duas tabelas diferentes.
Liste todos os IDs de produtos não vendidos.
![](https://i.imgur.com/BqSXk8f.png)
```sql=
SELECT Id
  FROM Product
EXCEPT
SELECT ProductId 
  FROM OrderItem
```

## SQL ALIAS
* Um Alias é um atalho para um nome de tabela ou coluna.
* Os aliases reduzem a quantidade de digitação necessária para inserir uma consulta.
* Consultas complexas com aliases geralmente são mais fáceis de ler.
* Aliases são úteis com JOINs e agregados: SUM , COUNT , etc.

**Exemplo**
Liste todos os nomes de clientes com uma coluna Nome.
```sql=
SELECT FirstName + ' ' + LastName AS Name,
       City, Country
  FROM Customer
```

### Sintaxe
Sintaxe para um alias de coluna.
```sql=
Coluna SELECT - nome AS alias - nome
  Tabela FROM - nome
ONDE condição
```

Sintaxe para um alias de tabela.
```sql=
coluna SELECT - nomes
  Tabela FROM - nome alias - nome
ONDE condição
```

**Exemplo**
SELECT com Aliases de Coluna e Tabela.
Liste o número de clientes em cada país. Exiba os resultados com cabeçalhos de coluna fáceis de entender.
![](https://i.imgur.com/j08dgys.png)
```sql=
SELECT C.Country, COUNT(C.Id) AS Customers 
  FROM Customer C
 GROUP BY C.Country
```
*Customers é um alias de coluna e C é um alias de tabela. Aliases de tabela são geralmente caracteres simples em maiúsculas.*

**Exemplo**
SELECT com ORDER BY, GROUP BY, Aliases.
Liste o valor total gasto pelo cliente com cabeçalhos de coluna fáceis de ler.
![](https://i.imgur.com/ojlVaZb.png)
```sql=
SELECT C.Id , C.LastName + ', ' + C.FirstName AS Customer, 
       SUM(O.TotalAmount) AS 'Total Spent'
  FROM [Order] O 
  JOIN Customer C ON O.CustomerId = C.Id
 GROUP BY C.Id, C.LastName + ', ' + C.FirstName
 ORDER BY SUM(O.TotalAmount) DESC
```
*Aliases de tabela simplificam a escrita de cláusulas JOIN e ORDER BY. O alias C.Id ajuda a identificar o ID do cliente versus o ID do pedido.*

## SQL WHERE com ANY, ALL
* Os operadores ANY e ALL são usados com WHERE ou HAVING.
* ANY e ALL operam em subconsultas que retornam vários valores.
* ANY retornará verdadeiro se algum dos valores da subconsulta atender à condição.
* ALL retorna verdadeiro se todos os valores da subconsulta atenderem à condição.

**Exemplo**
Liste todos os produtos que foram vendidos por mais de $ 45.
```sql=
SELECT ProductName AS 'Product'
  FROM Product
 WHERE Id = ANY
       (SELECT ProductId 
          FROM OrderItem 
         WHERE UnitPrice > 45)
```

### Sintaxe
QUALQUER sintaxe.
```sql=
coluna SELECT - nomes
  Tabela FROM - nome
coluna WHERE - operador de nome ANY
       ( coluna SELECT - nome
          Tabela FROM - nome
         ONDE condição )
```

TODA a sintaxe.
```sql=
coluna SELECT - nomes
  Tabela FROM - nome
coluna WHERE - operador de nome ALL
       ( coluna SELECT - nome
          Tabela FROM - nome
         ONDE condição )
```

**Exemplo**
ANY Subquery.
Liste os produtos que foram vendidos por unidade, ou seja, quantidade = 1.
![](https://i.imgur.com/BqSXk8f.png)
```sql=
SELECT ProductName AS 'Product'
  FROM Product
 WHERE Id = ANY
       (SELECT ProductId 
          FROM OrderItem 
         WHERE Quantity = 1)
```


**Exemplo**
ALL Subquery
Liste os clientes que fizeram pedidos maiores que a média de cada pedido do cliente.
![](https://i.imgur.com/ojlVaZb.png)
```sql=
SELECT DISTINCT FirstName + ' ' + LastName AS 'Customer'
  FROM Customer
  JOIN [Order] ON Customer.Id = [Order].CustomerId
   AND TotalAmount > ALL 
       (SELECT AVG(TotalAmount)
          FROM [Order]
         GROUP BY CustomerId)
```

## SQL WHERE EXISTS
* WHERE EXISTS testa se uma subconsulta retorna algum registro.
* EXISTS retorna verdadeiro se a subconsulta retornar um ou mais registros.
* EXISTS é comumente usado com subconsultas correlacionadas.

**Exemplo**
Liste os clientes com pedidos acima de $ 5.000.
```sql=
SELECT *
  FROM Customer
 WHERE EXISTS
       (SELECT Id
          FROM [Order]
         WHERE CustomerId = Customer.Id 
           AND TotalAmount > 5000)	
```

### Sintaxe
EXISTE a sintaxe.
```sql=
coluna SELECT - nomes
  Tabela FROM - nome
ONDE EXISTE
      ( coluna SELECT - nome
         Tabela FROM - nome
        ONDE condição )
```

**Exemplo**
EXISTS Subconsulta.
Encontre fornecedores com produtos acima de $ 100.
![](https://i.imgur.com/QL5Tr9C.png)
```sql=
SELECT CompanyName
  FROM Supplier
 WHERE EXISTS
       (SELECT ProductName
          FROM Product
         WHERE SupplierId = Supplier.Id 
           AND UnitPrice > 100)	
```
*Esta também é uma subconsulta correlacionada com Supplier.Id referenciando a consulta externa.*

## SQL INSERT INTO SELECT
* INSERT INTO SELECT copia dados de uma tabela para outra tabela.
* INSERT INTO SELECT requer que os tipos de dados nas tabelas de origem e destino correspondam.

**Exemplo**
Copie todos os clientes de Paris para a tabela Fornecedor.
```sql=
INSERT INTO Supplier (CompanyName, ContactName, City, Country, Phone)
SELECT FirstName + ' Company', FirstName + ' ' + LastName, City, Country, Phone
  FROM Customer
 WHERE City = 'Paris'
```

### Sintaxe
Sintaxe INSERT INTO SELECT.
```sql=
INSERT INTO nome - da-tabela ( nomes -da- coluna )
coluna SELECT - nomes
  Tabela FROM - nome
ONDE condição
```

**Exemplo**
INSERT SELECT.
Copie todos os fornecedores canadenses para a tabela Cliente.
![](https://i.imgur.com/X5bWfQX.png)
```sql=
INSERT INTO Customer (FirstName, LastName, City, Country, Phone)
SELECT LEFT(ContactName, CHARINDEX(' ',ContactName) - 1) AS FirstName, 
       SUBSTRING(ContactName, CHARINDEX(' ',ContactName) + 1, 100) AS LastName, 
       City, Country, Phone
  FROM Supplier
 WHERE Country = 'Canada'
```

## SQL TRUNCATE
* O comando TRUNCATE exclui todos os registros de uma tabela.
* TRUNCATE é semelhante a DELETE, mas é executado de forma muito mais rápida e eficiente.
* TRUNCATE não pode ser usado quando uma restrição de chave estrangeira impede a exclusão.

**Exemplo**
Exclua todos os registros do Fornecedor.
```sql=
TRUNCATE TABLE Supplier
```

### Sintaxe
Sintaxe TRUNCATE.
```sql=
TRUNCATE TABLE tabela - nome
```

## SQL COMMENTS
* Os comentários são usados ​​pelos desenvolvedores para descrever instruções ou lógica SQL.
* Comentários podem aparecer em qualquer lugar no código que é ignorado pelo SQL Server.
* Os comentários de linha única começam com um traço duplo: --.
* Comentários de várias linhas começam com a /*e terminam com um*/

**Exemplo**
Este exemplo tem um comentário descrevendo o SQL.
```sql=
/* 
 * List all customers from Sweden 
 */
SELECT FirstName, LastName, City, Country 
  FROM Customer
 WHERE Country = 'Sweden'
```
*Os comentários são ignorados e o SQL é executado normalmente.*

### Sintaxe
Sintaxe de linha única.
```sql=
-- Descrição do SQL
```

Sintaxe multilinha.
```sql=
/* Descrição do SQL
   descrição SQL
   descrição SQL
   Descrição SQL */
```

**Exemplo**
COMENTÁRIO DE UMA LINHA.
Uma consulta com um comentário de uma única linha.
```sql=
-- List all suppliers in Brazil

SELECT CompanyName, ContactName, City, Country, Phone
  FROM Supplier
 WHERE Country = 'Brazil'
```
*Novamente, o comentário é ignorado e o SQL é executado normalmente.*


**Exemplo**
COMENTÁRIO DE MÚLTIPLAS LINHAS
Comentários de várias linhas que descrevem a consulta.
```sql=
/************************************************
 * List the monthly orders for American customers 
 * for the year 2013. Order the list by month.
 ************************************************/

SELECT MONTH(OrderDate) AS Month,
       FirstName, LastName,
       SUM(TotalAmount) AS 'Monthly Sales'
  FROM [Order] O 
  JOIN Customer C ON C.Id = O.CustomerId
 WHERE Country = 'USA' AND YEAR(OrderDate) = 2013
 GROUP BY FirstName, LastName, MONTH(OrderDate)
 ORDER BY MONTH(OrderDate)
```
*Esse estilo de comentário é chamado de caixa de flores.*

**Exemplo**
COMENTÁRIO INLINE.
Use comentários embutidos para ocultar temporariamente o LastName da consulta.
```sql=
SELECT FirstName /*, LastName */ 
  FROM Customer
 WHERE Country = 'Sweden'
```

## SQL INJECTION
* SQL Injection é uma vulnerabilidade de segurança da web .
* Ele é usado por hackers para acessar e manipular o banco de dados.
* Isso é feito inserindo dados maliciosos em campos de entrada ou em URLs.
* SQL Injection é um dos vetores de ataque mais comuns contra aplicações web.

### Injeção via campos de entrada.
O SQL Injection é baseado no entendimento do intruso de como os aplicativos da Web são escritos, especificamente, como as consultas SQL dinâmicas são construídas usando a concatenação de strings.

Suponha que tenhamos um campo de entrada onde os funcionários são solicitados a verificar sua identidade com um número de funcionário exclusivo, assim:
![](https://i.imgur.com/WmWT4Ha.png)

E é nisso que o intruso entra:
![](https://i.imgur.com/InvSKHv.png)

A consulta agora será alterada para isso.
```sql=
SELECT FirstName , LastName , Salary 
  FROM Employee 
 WHERE EmployeeNumber = 78234 OR 1 = 1    
```
*Os resultados são bastante dramáticos. Esta consulta retorna todos os registros de funcionários com seus salários.*

**Explicação**
* A consulta foi projetada para recuperar um único registro de funcionário.
* Adicionar OR 1=1no campo de entrada mudará a consulta SQL.
* Como 1=1é sempre verdadeiro, a consulta retorna todos os funcionários e seus salários.

### Injeção via URL
O mesmo pode ser feito com URLs.

Suponha que os funcionários recebam um link por e-mail no qual podem clicar para acessar rapidamente seus dados pessoais. Este é o link:
`https://www.company.com/secure/employeenumber=78234`

Um funcionário mal-intencionado copia o link e acrescenta OR 1=1, assim:
`https://www.company.com/secure/employeenumber=78234+OR+1=1`

Você já pode adivinhar o que acontece quando essa URL é colocada no navegador. A mesma consulta maliciosa é criada, retornando todos os funcionários com seus salários.
```sql=
SELECT FirstName , LastName , Salary 
  FROM Employee 
 WHERE EmployeeNumber = 78234 OR 1 = 1
``` 
 
### Revisão de injeção de SQL
* A injeção de SQL é uma vulnerabilidade de segurança da web.
* Essa vulnerabilidade permite que o intruso penetre no banco de dados.
* A injeção SQL refere-se ao ato de injetar código malicioso em uma consulta SQL.
* A injeção pode ser feita a partir de um campo de entrada ou com alteração de URL.
* Se for bem-sucedido, um intruso pode acessar, modificar ou excluir dados do banco de dados.

### Injeção de SQL: how to
Um intruso geralmente começa sondando o site para encontrar vulnerabilidades. Isso é feito enviando dados incorretos ou qualquer outra carga incomum, forçando o site a criar mensagens de erro.

Ao observar a resposta, o intruso pode descobrir certos detalhes técnicos sobre o servidor ou o banco de dados. Por exemplo, se o site retornar erros de banco de dados para o usuário, isso pode revelar informações sobre a estrutura do banco de dados, como o fornecedor do banco de dados, nomes de tabelas, nomes de colunas, tipos de dados e muito mais.

A seguir, revisaremos alguns vetores de ataque.

### Acessar dados ocultos
SQL Injection pode ser usado para recuperar dados que normalmente são inacessíveis aos usuários.

Suponha que temos um site de comércio eletrônico.
Neste site, quando o usuário seleciona uma categoria, o navegador solicita esta URL:
`https://company.com/products?category=Computer`

Este link leva à seguinte consulta SQL.
```sql=
SELECT * 
  FROM Produto 
 WHERE Categoria = 'Computador' E Descontinuado = 0    
```

Ele retorna todos os produtos de informática que não foram descontinuados.

Em seguida, o intruso altera o URL acrescentando isto: '--, assim:
`https://company.com/products?category=Computer'--`

Supondo que o site não implemente nenhuma defesa contra a injeção SQL, o link alterado leva à seguinte consulta SQL.
```sql=
SELECT * 
  FROM Produto 
 WHERE Categoria = 'Computador' -- ' AND Descontinuado = 0  
```
 
A sequência de dois traços `--`é um comentário SQL, o que significa que o restante da consulta é ignorado. Isso remove a `Discontinued = 0` peça. A consulta retornará todos os produtos, sejam eles descontinuados ou não.

Depois disso, o intruso pode decidir exibir produtos de qualquer categoria, inclusive aquelas categorias que o usuário normalmente não vê, através deste link:
`https://yourstore.com/products?category=Computer'+OR+1=1--`

Isso leva à seguinte consulta:
```sql=
SELECT * 
  FROM Produto 
 WHERE Categoria = 'Computador' OU 1 = 1 -- ' E Descontinuado = 0  
```
Como `1=1` é sempre verdadeiro, esta consulta retornará uma lista completa de todos os produtos de qualquer categoria, com desconto ou não.

### Ignorando a lógica de login
A maioria dos aplicativos da Web possui um formulário de login que aceita um e-mail e uma senha. Ao enviar credenciais, por exemplo, "jimmy@gmail.com" e "mypassword", o usuário será validado com esta consulta.
```sql=
SELECT * 
  FROM Cliente 
 WHERE E-mail = 'jimmy@gmail.com' E senha = 'minha senha' 
 ```  

Se a consulta retornar um registro de cliente, o login foi bem-sucedido, caso contrário, falhou.

Usando a injeção de SQL, um intruso pode conseguir fazer login sem uma senha anexando um comentário SQL ao e-mail. Eles tentarão enviar "jimmy@gmail.com'--'" com uma senha arbitrária, o que leva a esta consulta:
```sql=
SELECT * 
  FROM Cliente 
 WHERE Nome de usuário = 'jimmy@gmail.com' -- ' E senha = ' mysecret123 '
``` 
 
A cláusula de senha nesta consulta é ignorada devido ao comentário `--`que segue o valor do e-mail. Esta consulta retorna um registro do cliente "jimmy@gmail.com" e o intruso está logado com sucesso. Tudo o que o intruso precisa é de um e-mail válido.

### Recuperando dados de outras tabelas
Essa técnica de injeção SQL usa a UNIONpalavra-chave. A UNIONpalavra-chave permite que um intruso execute uma SELECTconsulta adicional e tenha os resultados anexados a uma consulta existente.

Digamos, um aplicativo executa esta consulta.
```sql=
SELECT Email , Nome 
  FROM Cliente 
 WHERE Departamento = 'Marketing'  
```

Um intruso pode enviar a entrada necessária que efetivamente anexa esta string:
```sql=
  UNION SELECT E-mail , Senha DE [ Usuário ]-- 
```

Esta é a consulta resultante.
```sql=
SELECT Email , Nome 
  FROM Cliente 
 WHERE Departamento = 'Marketing' 
UNION 
SELECT Email , Senha  
  FROM [ Usuário ]--    
```

A execução desta consulta retornará uma lista de clientes junto com uma lista de credenciais de login de todos os usuários. Bastante devastador.

### Obtendo informações do banco de dados
Um intruso pode tentar obter informações sobre a estrutura do banco de dados do banco de dados. A sequência a seguir pode ser anexada a um valor de entrada com uma `UNION` palavra-chave.
```sql=
SELECT * FROM INFORMATION_SCHEMA.TABLES
```

Isso retornaria uma lista de todas as tabelas no banco de dados. Como se trata de uma UNION, o intruso precisará garantir que as colunas correspondam à primeira e à segunda consulta.

### Prevenção de injeção de SQL
A injeção de SQL é possível devido à forma como as consultas SQL são construídas no código. Se a entrada bruta do usuário for usada para simplesmente encadear uma consulta SQL, isso abrirá o site para ataques de injeção SQL. Então, como isso pode ser evitado?

A maioria das instâncias de injeção de SQL pode ser evitada usando **consultas parametrizadas** (também conhecidas como **instruções preparadas** ). Consultas parametrizadas são consultas SQL que aceitam a entrada do usuário de maneira mais controlada usando **parâmetros SQL** . Um parâmetro SQL é um espaço reservado em uma consulta que aceita um valor de dados inserido pelo usuário.

Aqui está uma instrução SELECT com parâmetros SQL:
```sql=
var id = GetRequestString("ProductId");
var sql = "SELECT * FROM Product WHERE ProductId = @0";

db.Execute(sql, id);
```

Os parâmetros são especificados na instrução SQL por um @. O mecanismo SQL verifica cada valor de parâmetro e garante que seja um literal válido e não contenha código SQL executável.

Dependendo do idioma e da plataforma, escrever declarações preparadas será um pouco diferente. Aqui está outra declaração preparada usando o Entity Framework Core.
```sql=
var customer = db.Customers.FromSqlRaw(
      "SELECT * FROM Customer WHERE Id = {0}", id).FirstOrDefault();
```
      
Os parâmetros SQL podem ser usados em qualquer instrução SQL que contenha entrada do usuário. Aqui está uma instrução INSERT.

```sql=
context.Database.ExecuteSqlCommand(
    "INSERT INTO Customer (FirstName, LastName) VALUES(@firstName, @lastName)",
    new SqlParameter("@firstName", firstName),
    new SqlParameter("@lastName", lastName)
);
```
     
Aplicativos que aceitam entrada do usuário, mas não podem usar parâmetros SQL, precisam adotar uma abordagem diferente. A lista branca de valores de entrada permitidos é uma maneira possível.

Outra forma de prevenir SQL Injection é estudar primeiro as possíveis vulnerabilidades e depois removê-las uma a uma com código personalizado. Claramente, isso requer grandes habilidades de segurança e experiência da equipe de desenvolvimento.

### Folha de Risco de Injeção de SQL
Esta folha de risco lista as técnicas de SQL que são comumente usadas durante um ataque de SQL Injection. Os exemplos de código são específicos do SQL Server. Para outros bancos de dados, a sintaxe será um pouco diferente, mas os fundamentos são os mesmos.

**Comments**
Os comentários podem ser usados ​​para remover uma parte da consulta original. O SQL Server oferece suporte a dois tipos de comentários.
```sql=
--
```
e
```sql=
/* comment */
```

### Concatenação de strings
Várias strings podem ser combinadas para criar uma única string usando concatenação. Intrusos usam isso a seu favor, concatenando strings de maneiras inesperadas.
```sql=
'value1'+'value2'
```

### Substring
A função SUBSTRING extrai parte de uma string com um comprimento especificado. SUBSTRING pode ocultar funções do sistema e fazer parte de instruções SELECT, INSERT ou UPDATE. Este exemplo revelará o banco de dados e sua versão.
```sql=
SELECT SUBSTRING(@@version,1,90)
```

Isso retornará algo como isto: 'Microsoft SQL Server 2016 (SP2-GDR) (KB4583460) - 13.0.5103.6 (X64) Nov 1 2020 00:13:28'. Armado com essas informações, o intruso pode atacar com mais precisão esse banco de dados.

### Metadados do banco de dados
INFORMAÇÃO_SCHEMA é um padrão ANSI que retorna metadados sobre um banco de dados. Isso pode incluir informações sobre tabelas, colunas, restrições, índices e muito mais. Por exemplo, um intruso pode obter informações da tabela com esta consulta.
```sql=
SELECT * FROM INFORMATION_SCHEMA.TABLES
```

Nosso banco de dados de amostra retornaria esta lista com nomes de tabelas:
![](https://i.imgur.com/4ktRJG9.png)

### Erros condicionais
O intruso pode usar erros condicionais para testar certas condições do banco de dados. Se a condição for verdadeira, um erro de divisão por zero é acionado, validando o teste. Aqui está o SQL.
```sql=
SELECT CASE WHEN (CONDITION-HERE) THEN 1/0 ELSE NULL END
```

### Consultas em lote
Consultas em lote é a execução de várias consultas em uma única operação (elas são agrupadas em lote). No SQL Server, várias consultas podem ser agrupadas colocando um ;(ponto-e-vírgula) entre as consultas individuais, dessa forma.
```sql=
QUERY1; QUERY2; QUERY3
```

## SQL KEYWORDS
* O SQL Server usa palavras-chave reservadas para operações de banco de dados.
* Essas palavras-chave fazem parte da gramática T-SQL do SQL Server.
* O SQL Server reivindicou palavras reservadas atuais e futuras.
* Palavras-chave podem ser usadas como identificadores, colocando-as entre `[ ](colchetes)`.

### Keywords T-SQL atuais
Keywords que são usadas atualmente pelo T-SQL.
|||||
|--|--|--|--|
|ADD	|EXCEPT	|PERCENT| ALL	|
|EXEC	|PLAN| ALTER|	EXECUTE|	
|PRECISION| AND|	EXISTS|	PRIMARY|
|ANY|	EXIT|	PRINT|AS|	
|FETCH|	PROC|ASC|	FILE|	
|PROCEDURE|AUTHORIZATION|	FILLFACTOR	|PUBLIC|
|BACKUP|	FOR|	RAISERROR|BEGIN|
|FOREIGN|	READ|BETWEEN|	FREETEXT|	
|READTEXT|BREAK|	FREETEXTTABLE|	RECONFIGURE|
|BROWSE|	FROM|	REFERENCES|BULK|	
|FULL|	REPLICATION|BY|	FUNCTION|	
|RESTORE|CASCADE|	GOTO|	RESTRICT|
|CASE|	GRANT|	RETURN|CHECK|	
|GROUP|	REVOKE|CHECKPOINT|	HAVING|	
|RIGHT|CLOSE|	HOLDLOCK|	ROLLBACK|
|CLUSTERED|	IDENTITY|	ROWCOUNT|COALESCE|	
|IDENTITY_INSERT|	ROWGUIDCOL|COLLATE|	IDENTITYCOL|	
|RULE|COLUMN|	IF|	SAVE|
|COMMIT|	IN|	SCHEMA|COMPUTE|	
|INDEX|	SELECT|CONSTRAINT|	INNER|	
|SESSION_USER|CONTAINS|	INSERT|	SET|
|CONTAINSTABLE|	INTERSECT|	SETUSER|CONTINUE|	
|INTO|	SHUTDOWN|CONVERT|	IS|	
|SOME|CREATE|	JOIN|	STATISTICS|
|CROSS|	KEY|	SYSTEM_USER|CURRENT|	
|KILL|	TABLE|CURRENT_DATE|	LEFT|	
|TEXTSIZE|CURRENT_TIME|	LIKE|	THEN|
|CURRENT_TIMESTAMP|	LINENO|	TO|CURRENT_USER|	
|LOAD|	TOP|CURSOR|	NATIONAL|	
|TRAN|DATABASE|	NOCHECK|	TRANSACTION|
|DBCC|	NONCLUSTERED|	TRIGGER|DEALLOCATE|	
|NOT|	TRUNCATE|DECLARE|	NULL|	
|TSEQUAL|DEFAULT|	NULLIF|	UNION|
|DELETE|	OF|	UNIQUE|DENY|	
|OFF|	UPDATE|DESC|	OFFSETS|	
|UPDATETEXT|DISK|	ON|	USE|
|DISTINCT|	OPEN|	USER|DISTRIBUTED|	
|OPENDATASOURCE|	VALUES|DOUBLE|	OPENQUERY|	
|VARYING|DROP|	OPENROWSET|	VIEW|
|DUMMY|	OPENXML|	WAITFOR|DUMP|	
|OPTION|	WHEN|ELSE|	OR|	
|WHERE|END|ORDER|	WHILE|
|ERRLVL|	OUTER|	WITH|ESCAPE|	
|OVER|	WRITETEXT|

### Keywords T-SQL futuras
Palavras-chave que o SQL Server reserva para uso futuro potencial.
|||||
|--|--|--|--|
|ABSOLUTE|	FOUND|	PRESERVE|ACTION|
|FREE|	PRIOR|ADMIN|	GENERAL|
|PRIVILEGES|AFTER|	GET|	READS|
|AGGREGATE|	GLOBAL|	REAL|ALIAS|
|GO|	RECURSIVE|ALLOCATE|	GROUPING|
|REF|ARE|	HOST|	REFERENCING|
|ARRAY|	HOUR|	RELATIVE|ASSERTION|
|IGNORE|	RESULT|AT|	IMMEDIATE|
|RETURNS|BEFORE|	INDICATOR|	ROLE|
|BINARY|	INITIALIZE|	ROLLUP|BIT|
|INITIALLY|	ROUTINE|BLOB|	INOUT|
|ROW|BOOLEAN|	INPUT|	ROWS|
|BOTH|	INT|	SAVEPOINT|BREADTH|
|INTEGER|	SCROLL|CALL|	INTERVAL|
|SCOPE|CASCADED|	ISOLATION|	SEARCH|
|CAST|	ITERATE|	SECOND|CATALOG|
|LANGUAGE|	SECTION|CHAR|	LARGE|
|SEQUENCE|CHARACTER|	LAST|	SESSION|
|CLASS|	LATERAL|	SETS|CLOB|
|LEADING|	SIZE|COLLATION|	LESS|
|SMALLINT|COMPLETION|	LEVEL|	SPACE|
|CONNECT|	LIMIT|	SPECIFIC|CONNECTION|
|LOCAL|	SPECIFICTYPE|CONSTRAINTS|	LOCALTIME|
|SQL|CONSTRUCTOR|	LOCALTIMESTAMP|	SQLEXCEPTION|
|CORRESPONDING|	LOCATOR|	SQLSTATE|CUBE|
|MAP|	SQLWARNING|CURRENT_PATH|	MATCH|
|START|CURRENT_ROLE|	MINUTE|	STATE|
|CYCLE|	MODIFIES|	STATEMENT|DATA|
|MODIFY|	STATIC|DATE|	MODULE|
|STRUCTURE|DAY|	MONTH|	TEMPORARY|
|DEC|	NAMES|	TERMINATE|DECIMAL|
|NATURAL|	THAN|DEFERRABLE|	NCHAR|
|TIME|DEFERRED|	NCLOB|	TIMESTAMP|
|DEPTH|	NEW|	TIMEZONE_HOUR|DEREF|
|NEXT|	TIMEZONE_MINUTE|DESCRIBE|	NO|
|TRAILING|DESCRIPTOR|	NONE|	TRANSLATION|
|DESTROY|	NUMERIC|	TREAT|DESTRUCTOR|
|OBJECT|	TRUE|DETERMINISTIC|	OLD|
|UNDER|DICTIONARY|	ONLY|	UNKNOWN|
|DIAGNOSTICS|	OPERATION|	UNNEST|DISCONNECT|
|ORDINALITY|	USAGE|DOMAIN|	OUT|
|USING|DYNAMIC|	OUTPUT|	VALUE|
|EACH|	PAD|	VARCHAR|END-EXEC|
|PARAMETER|	VARIABLE|EQUALS|	PARAMETERS|
|WHENEVER|EVERY|	PARTIAL|	WITHOUT|
|EXCEPTION|	PATH|	WORK|EXTERNAL|	
|POSTFIX|	WRITE|FALSE|	PREFIX|
|YEAR|FIRST|	PREORDER|	ZONE|
|FLOAT|	PREPARE|

----

FORNECEDOR/SUPLIER
![](https://i.imgur.com/pHCUVAx.png)

PEDIDO/ORDER
![](https://i.imgur.com/Avst8fD.png)

CLIENTE/CUSTOMER
![](https://i.imgur.com/j08dgys.png)

PRODUTOS/PRODICTS
![](https://i.imgur.com/CRZodgp.png)

CLIENTE E FORNECEDOR
![](https://i.imgur.com/X5bWfQX.png)

CLIENTE E PEDIDO
![](https://i.imgur.com/ojlVaZb.png)

ORDEM PRODUCT / ITEM PEDIDO e PRODUTO
![](https://i.imgur.com/BqSXk8f.png)


ORDER / CUSTOMER OU ORDEM / CLIENTE
![](https://i.imgur.com/ojlVaZb.png)

ORDEM ITEM E PRODUCT
![](https://i.imgur.com/BqSXk8f.png)


PRODUCT E SUPLLIER / PRODUTO E FORNECEDOR
![](https://i.imgur.com/QL5Tr9C.png)


526666205






###### tags: `sql` `sefaz/al`