SQL CREATE TABLE

Até aqui você só usou tabelas que já existiam: clientes, produtos, pedidos… Agora a Ana quer guardar uma coisa nova: as avaliações que os clientes deixam nos produtos da Loja Aurora ("chegou rápido, nota 5"). Não existe tabela para isso, então ela vai criar uma. O comando é o CREATE TABLE ("crie a tabela"). Nesta aula você vai criar tabelas, conferir o que foi criado e conhecer os erros mais comuns, inclusive um que não dá erro nenhum e estraga a tabela em silêncio.

Você vai aprender
  • O que é criar uma tabela: definir o nome dela e as colunas, antes de existir qualquer dado.
  • A forma do CREATE TABLE: nome, parênteses, colunas separadas por vírgula, cada uma com o seu tipo.
  • Como colocar as primeiras linhas na tabela nova e como conferir o que foi criado (sqlite_schema, PRAGMA table_info, .schema).
  • Boas regras para dar nome a tabelas e colunas, e as palavras que o SQL reserva para si.
  • IF NOT EXISTS: criar só se ainda não existir, e a pegadinha dele.
  • As mensagens reais do SQLite quando a tabela já existe, quando sobra uma vírgula, quando uma coluna se repete, e o que acontece quando falta uma vírgula.

Lembre-se: no editor do guia, cada Rodar parte do banco limpo da Loja Aurora. A tabela que você criar existe só durante aquela execução; ao rodar de novo, ela some e o banco volta ao original. Por isso os exemplos desta aula sempre trazem o CREATE TABLE junto com o que vem depois (o INSERT, o SELECT), na mesma caixa.


A ideia: o cabeçalho da planilha

Pense numa planilha nova, em branco. Antes de anotar a primeira avaliação, a Ana escreve na primeira linha os títulos das colunas: "número", "produto", "nota", "comentário". Ela ainda não tem nenhuma avaliação, mas já decidiu o que vai anotar de cada uma.

| id | produto_id | nota | comentario |
|----|------------|------|------------|
|    |            |      |            |   ← ainda vazia

Num banco de dados é igual, com uma diferença importante: o banco é mais exigente que a planilha. Cada coluna ganha um nome e um tipo (número inteiro, texto, número com casas decimais…), e pode ganhar regras ("esta coluna não pode ficar vazia"). Tudo isso se escreve uma vez só, no CREATE TABLE. Depois, cada INSERT só preenche as linhas.

Na planilhaNo bancoComando
Criar a aba "Avaliações" e escrever os títulos das colunasCriar a tabela avaliacoes com as suas colunasCREATE TABLE
Anotar uma avaliação numa linhaInserir uma linhaINSERT INTO (aula INSERT INTO)
Olhar a abaConsultar a tabelaSELECT (aula SELECT)

1. A primeira tabela

Aqui está a tabela de avaliações. O SELECT logo depois serve para você ver a tabela que acabou de nascer:

CREATE TABLE avaliacoes (
    id         INTEGER,
    produto_id INTEGER,
    nota       INTEGER,
    comentario TEXT
);

SELECT * FROM avaliacoes;

O resultado mostra o "CREATE TABLE: ok" e uma tabela com as quatro colunas e nenhuma linha. É a planilha com o cabeçalho escrito e nada embaixo.

CREATE TABLE
"Crie a tabela." As duas palavras-chave que abrem o comando.
avaliacoes
O nome da tabela nova. Sem acento, sem espaço, em minúsculas (as regras estão na seção 5).
( … )
Os parênteses guardam a lista de colunas. Abre depois do nome, fecha depois da última coluna.
id INTEGER
Uma coluna: primeiro o nome (id), depois o tipo (INTEGER, "inteiro": números sem vírgula, como 1, 2, 3).
,
A vírgula separa uma coluna da outra. Vai entre as colunas: depois da última não tem vírgula.
comentario TEXT
A última coluna, do tipo TEXT ("texto"): qualquer frase.
;
O ponto e vírgula termina o comando, como em qualquer SQL.

As colunas desta tabela seguem o mesmo jeito das tabelas da Loja Aurora: id é o número da avaliação, produto_id diz qual produto foi avaliado (o mesmo número do id em produtos), nota vai de 1 a 5 e comentario é o texto do cliente.

Uma coluna por linha

O SQL não liga para quebras de linha nem para espaços a mais: CREATE TABLE avaliacoes (id INTEGER, produto_id INTEGER, nota INTEGER, comentario TEXT); numa linha só cria exatamente a mesma tabela. Mas escrever uma coluna por linha, com os tipos alinhados, deixa o comando fácil de ler e de conferir. É assim que estão escritas as tabelas da Loja Aurora, e é assim que você vai ver em quase todo projeto.


2. Os tipos mais usados

Cada coluna tem um tipo. Os tipos têm duas aulas só para eles (Tipos de Dados e Os Tipos no SQLite); por enquanto, quatro bastam para quase tudo:

TipoGuardaExemplo na Loja Aurora
INTEGERNúmeros inteirosestoque em produtos, quantidade em itens_pedido
REALNúmeros com casas decimaispreco em produtos, frete em pedidos
TEXTTextonome, email, cidade em clientes
TEXT com dataDatas no formato AAAA-MM-DDdata em pedidos, nascimento em clientes

Uma tabela para os cupons de desconto da loja usa três deles: o código do cupom é texto, o desconto tem casas decimais e a validade é uma data.

CREATE TABLE cupons (
    codigo   TEXT,
    desconto REAL,
    validade TEXT
);

INSERT INTO cupons (codigo, desconto, validade)
VALUES ('AURORA10', 10, '2026-12-31');

SELECT * FROM cupons;

Repare no resultado: a Ana escreveu 10, mas o SELECT mostra 10.0. A coluna é REAL, então o SQLite guardou o número como número com casas decimais. É o tipo da coluna trabalhando. Datas são guardadas como texto no SQLite ('2026-12-31', entre aspas simples); a aula Datas e Horas explica por quê.

Experimente: a Ana tentou criar a tabela de cupons, mas o comando deu erro. Rode, leia a mensagem em vermelho e conserte. (Dica: olhe o fim da lista de colunas.)

CREATE TABLE cupons (
    codigo   TEXT,
    desconto REAL,
    validade TEXT,
);
CREATE TABLE cupons (
    codigo   TEXT,
    desconto REAL,
    validade TEXT
);

3. As primeiras linhas

Tabela criada, agora é só usar o INSERT INTO que você já conhece (aula INSERT INTO). Duas avaliações do produto 3, o Lápis Grafite HB:

CREATE TABLE avaliacoes (
    id         INTEGER,
    produto_id INTEGER,
    nota       INTEGER,
    comentario TEXT
);

INSERT INTO avaliacoes (id, produto_id, nota, comentario)
VALUES (1, 3, 5, 'Chegou rápido');

INSERT INTO avaliacoes (id, produto_id, nota, comentario)
VALUES (2, 3, 4, 'Bom, mas a caixa veio amassada');

SELECT * FROM avaliacoes;

O quadro mostra os três passos, na ordem: "CREATE TABLE: ok", depois "1 linha afetada" duas vezes (um para cada INSERT) e, por fim, a tabela com as duas avaliações.

E se o cliente não escreveu comentário? Basta deixar a coluna de fora do INSERT. Como a tabela não tem nenhuma regra dizendo o contrário, a coluna esquecida fica vazia, com NULL (aula O Valor NULL):

CREATE TABLE avaliacoes (
    id         INTEGER,
    produto_id INTEGER,
    nota       INTEGER,
    comentario TEXT
);

INSERT INTO avaliacoes (id, produto_id, nota)
VALUES (3, 1, 2);

SELECT * FROM avaliacoes;

Às vezes é isso que você quer; às vezes não (uma avaliação sem nota não serve para nada). Para proibir o vazio, ou para pôr um valor automático no lugar dele, existem as restrições que você vai ver nas próximas aulas: NOT NULL e DEFAULT.


4. Conferir o que foi criado

Criou a tabela e quer ver como ela ficou? Há três jeitos, e cada um serve num lugar.

No editor: a tabela sqlite_schema

Todo banco SQLite tem uma tabela especial, a sqlite_schema ("o esquema do SQLite"), com uma linha para cada tabela do banco e o CREATE TABLE que a criou. Ela se consulta com um SELECT comum:

CREATE TABLE avaliacoes (id INTEGER, produto_id INTEGER, nota INTEGER, comentario TEXT);

SELECT name, sql FROM sqlite_schema WHERE type = 'table';
sqlite_schema
A tabela onde o SQLite anota o próprio banco: o que existe nele.
name
O nome de cada tabela. A sua avaliacoes aparece por último, ao lado das sete da Loja Aurora.
sql
O CREATE TABLE que criou aquela tabela, guardado do jeito que foi escrito. É a melhor forma de descobrir quais colunas e regras uma tabela tem.
WHERE type = 'table'
Só as tabelas. A sqlite_schema também guarda índices e views (aulas Índices e Views).

No editor: PRAGMA table_info

O PRAGMA table_info(tabela) mostra as colunas uma por linha, já separadas em partes. Os PRAGMAs são comandos próprios do SQLite (aula PRAGMAs Úteis):

CREATE TABLE avaliacoes (id INTEGER, produto_id INTEGER, nota INTEGER, comentario TEXT);

PRAGMA table_info(avaliacoes);
Coluna do resultadoO que diz
cidA posição da coluna, contando do 0
nameO nome da coluna
typeO tipo que você escreveu
notnull1 se a coluna tem a regra NOT NULL (aula NOT NULL), 0 se não
dflt_valueO valor padrão (aula DEFAULT); NULL se não tem
pkDiferente de 0 se a coluna faz parte da chave primária (aula PRIMARY KEY)

Rode o mesmo PRAGMA numa tabela da loja e você já vê as regras que ela tem: em clientes, o nome tem notnull 1 e o vip tem valor padrão 0.

PRAGMA table_info(clientes);

No terminal: .tables e .schema

No programa sqlite3 (aula O Terminal do SQLite), os comandos de ponto .tables e .schema fazem o mesmo trabalho com menos digitação. Eles não existem no editor, só no terminal (aula Comandos de Ponto). A Ana abriu o banco da loja, criou a tabela e conferiu:

$ sqlite3 loja.db
SQLite version 3.50.4 2025-07-30 19:33:53
Enter ".help" for usage hints.
sqlite> CREATE TABLE avaliacoes (id INTEGER, produto_id INTEGER, nota INTEGER, comentario TEXT);
sqlite> .tables
avaliacoes    clientes      funcionarios  pedidos
categorias    fornecedores  itens_pedido  produtos
sqlite> .schema avaliacoes
CREATE TABLE avaliacoes (id INTEGER, produto_id INTEGER, nota INTEGER, comentario TEXT);
sqlite> .quit

Repare que o CREATE TABLE que deu certo não imprime nada: no terminal, silêncio quer dizer "deu certo". A tabela nova já aparece no .tables, em ordem alfabética, e o .schema devolve o comando que a criou. Diferente do editor, aqui a tabela fica gravada no arquivo loja.db: na próxima vez que a Ana abrir o banco, ela continua lá.


5. Como dar nome a tabelas e colunas

O SQLite aceita muita coisa como nome, mas nem tudo que ele aceita é uma boa ideia. As regras que o guia (e a maioria dos projetos) segue:

RegraBomEvitePor quê
MinúsculasavaliacoesAvaliacoes, AVALIACOESFica fácil separar o que é palavra do SQL (maiúscula) do que é nome seu (minúscula)
Sem espaço: use _produto_idproduto idCom espaço, o SQL acha que são duas palavras e dá erro
Sem acento nem çavaliacoes, descricaoavaliações, descriçãoO SQLite aceita, mas outros programas e bancos podem tropeçar, e ninguém lembra onde estava o acento
Comece por letravendas_20262026_vendasComeçando por número, o SQLite não reconhece o nome
Tabela no plural, coluna no singularclientes, nomecliente, nomesA tabela guarda muitos clientes; cada coluna guarda um valor por linha. É o padrão da Loja Aurora
Nada de palavra reservadapedidos, ordemorder, select, tableSão palavras do próprio SQL (veja abaixo)

E maiúscula ou minúscula faz diferença? Para o SQLite, não: Avaliacoes e avaliacoes são o mesmo nome. Tanto que, se a Ana criar a Avaliacoes e depois tentar criar a avaliacoes, a segunda dá erro:

CREATE TABLE Avaliacoes (id INTEGER);
CREATE TABLE avaliacoes (id INTEGER);

Palavras reservadas

Algumas palavras são do próprio SQL: SELECT, FROM, WHERE, ORDER, TABLE, GROUP… São as palavras reservadas. Uma tabela de "ordens de serviço" chamada order parece uma boa ideia, mas o SQLite lê order como o começo de um ORDER BY e se perde:

CREATE TABLE order (id INTEGER);

Dá para forçar com aspas duplas (CREATE TABLE "order" (…)): no SQL padrão, aspas duplas marcam um nome, e então qualquer palavra vale. Só que aí você vai ter de escrever "order" com aspas em todas as consultas, para sempre. Escolha outro nome (ordens, ordens_servico) e economize a dor de cabeça. A lista completa está em Palavras-chave SQL.


6. IF NOT EXISTS: criar só se não existir

A Loja Aurora já tem uma tabela fornecedores. O que acontece se alguém tentar criá-la de novo?

CREATE TABLE fornecedores (id INTEGER, nome TEXT);

"A tabela fornecedores já existe." O SQLite não deixa duas tabelas com o mesmo nome no mesmo banco, e para tudo ali. Isso incomoda quando você tem um roteiro (um arquivo .sql com vários comandos, como o que monta a Loja Aurora) que precisa rodar mais de uma vez: na segunda vez, o primeiro CREATE TABLE já derruba o roteiro inteiro.

Para isso existe o IF NOT EXISTS ("se não existir"):

CREATE TABLE IF NOT EXISTS fornecedores (id INTEGER, nome TEXT);

SELECT count(*) FROM fornecedores;
CREATE TABLE
O comando de sempre.
IF NOT EXISTS
"Se não existir." Vem entre TABLE e o nome. Se a tabela ainda não existe, ela é criada normalmente. Se já existe, o comando não faz nada e não dá erro.
fornecedores (…)
O nome e as colunas, como sempre.

O editor mostrou "CREATE TABLE: ok" e o count(*) continua 6: os seis fornecedores estão lá, intactos. O comando simplesmente não fez nada.

A pegadinha: ele não compara as colunas

O IF NOT EXISTS só olha o nome. Se já existe uma tabela com esse nome, ele desiste, mesmo que ela tenha colunas totalmente diferentes das que você escreveu. Veja: a Ana pediu uma clientes com as colunas codigo e apelido. Nada de erro, e nada mudou:

CREATE TABLE IF NOT EXISTS clientes (codigo INTEGER, apelido TEXT);

PRAGMA table_info(clientes);

A tabela continua com as sete colunas de sempre (id, nome, email…), sem codigo nem apelido. Se o seu programa contava com essas colunas, o erro só vai aparecer lá na frente, numa consulta. Para mudar as colunas de uma tabela que já existe, o comando é outro: ALTER TABLE.

No terminal é igual: sem IF NOT EXISTS, o erro; com ele, silêncio. Aqui a mensagem vem com o prefixo Parse error: e uma setinha embaixo do ponto do problema:

$ sqlite3 loja.db
SQLite version 3.50.4 2025-07-30 19:33:53
Enter ".help" for usage hints.
sqlite> CREATE TABLE avaliacoes (id INTEGER, produto_id INTEGER, nota INTEGER, comentario TEXT);
sqlite> CREATE TABLE avaliacoes (id INTEGER);
Parse error: table avaliacoes already exists
  CREATE TABLE avaliacoes (id INTEGER);
               ^--- error here
sqlite> CREATE TABLE IF NOT EXISTS avaliacoes (id INTEGER);
sqlite> .quit

Experimente: este roteiro cria a tabela de avaliações, mas foi escrito para um banco onde a tabela talvez já exista, e por isso ele precisa do IF NOT EXISTS. Só que a Ana escreveu as palavras na ordem errada, e o comando deu erro. Conserte a ordem e rode: a tabela tem de ser criada e receber a avaliação.

CREATE TABLE avaliacoes IF NOT EXISTS (
    id         INTEGER,
    produto_id INTEGER,
    nota       INTEGER,
    comentario TEXT
);

INSERT INTO avaliacoes (id, produto_id, nota, comentario)
VALUES (1, 10, 5, 'Carrega o celular bem rápido');
CREATE TABLE IF NOT EXISTS avaliacoes (
    id         INTEGER,
    produto_id INTEGER,
    nota       INTEGER,
    comentario TEXT
);

INSERT INTO avaliacoes (id, produto_id, nota, comentario)
VALUES (1, 10, 5, 'Carrega o celular bem rápido');

7. Uma tabela de verdade: tipos e regras

As tabelas que você criou até aqui só têm nome e tipo em cada coluna. As tabelas da Loja Aurora têm mais coisa. Veja como foi criada a tabela produtos:

SELECT sql FROM sqlite_schema WHERE name = 'produtos';

Depois do tipo, várias colunas têm restrições (em inglês, constraints): regras que o banco confere a cada INSERT e UPDATE, e que recusam o dado errado com uma mensagem de erro. Cada uma tem a sua aula, logo a seguir:

RestriçãoNa tabela produtosQuer dizerAula
PRIMARY KEYid INTEGER PRIMARY KEYO número que identifica cada produto: único e nunca vazioPRIMARY KEY
NOT NULLnome TEXT NOT NULLTodo produto tem de ter nomeNOT NULL
DEFAULTestoque INTEGER NOT NULL DEFAULT 0Se o INSERT não disser o estoque, ele começa em 0DEFAULT
REFERENCEScategoria_id … REFERENCES categorias(id)A categoria tem de existir na tabela categoriasFOREIGN KEY

Uma versão mais caprichada da tabela de avaliações, com essas regras, ficaria assim. Você vai entender cada pedaço nas próximas aulas; por enquanto, repare que a estrutura é a mesma: nome da coluna, tipo, e as regras no fim da linha.

CREATE TABLE avaliacoes (
    id         INTEGER PRIMARY KEY,
    produto_id INTEGER NOT NULL REFERENCES produtos(id),
    nota       INTEGER NOT NULL,
    comentario TEXT,
    criada_em  TEXT NOT NULL DEFAULT CURRENT_DATE
);

PRAGMA table_info(avaliacoes);

Formas diferentes de criar uma tabela

FormaExemploQuando usar
Uma coluna por linhaCREATE TABLE avaliacoes (
  id INTEGER,
  nota INTEGER
);
Sempre que der: é a mais fácil de ler e de conferir
Tudo numa linhaCREATE TABLE avaliacoes (id INTEGER, nota INTEGER);Tabelas pequenas, testes rápidos no terminal
Com IF NOT EXISTSCREATE TABLE IF NOT EXISTS avaliacoes (…);Roteiros que podem rodar mais de uma vez (lembre: não compara as colunas)
A partir de uma consultaCREATE TABLE baratos AS SELECT …;Copiar um pedaço de outra tabela (aula Criar Tabela a partir de Consulta)
Sem tiposCREATE TABLE avaliacoes (id, nota);Nunca. O SQLite aceita, mas os outros bancos não, e você perde a ajuda do tipo (aula Os Tipos no SQLite)

Quando dá errado

Num CREATE TABLE, quase todo erro é de digitação: uma vírgula, um parêntese, uma palavra trocada. Os quadros abaixo rodam o SQL errado de verdade e mostram a mensagem do SQLite.

Sobrou uma vírgula depois da última coluna
CREATE TABLE avaliacoes (
    id         INTEGER,
    nota       INTEGER,
    comentario TEXT,
);

O que diz: near ")": syntax error, "erro de sintaxe perto do )". Depois de uma vírgula, o SQLite espera mais uma coluna, e encontrou o parêntese de fechamento. É o erro mais comum de todos, porque acontece quando você apaga a última coluna e esquece a vírgula da penúltima. No terminal, a seta aponta o lugar:

$ sqlite3 loja.db
SQLite version 3.50.4 2025-07-30 19:33:53
Enter ".help" for usage hints.
sqlite> CREATE TABLE teste (id INTEGER,);
Parse error: near ")": syntax error
  CREATE TABLE teste (id INTEGER,);
                   error here ---^
sqlite> .quit

Como consertar: apague a vírgula da última coluna. Vírgula só entre colunas.

Faltou uma vírgula (e o SQLite não reclamou!)

Este é traiçoeiro. A Ana esqueceu a vírgula entre produto_id e nota:

CREATE TABLE avaliacoes (
    id         INTEGER,
    produto_id INTEGER
    nota       INTEGER
);

PRAGMA table_info(avaliacoes);

O que acontece: "CREATE TABLE: ok". Nenhum erro! Mas o PRAGMA mostra que a tabela ficou com duas colunas, e não três: a coluna produto_id ganhou um tipo esquisito, que começa em INTEGER e vai até o INTEGER da linha de baixo, com a quebra de linha e os espaços no meio (numa linha só, seria INTEGER nota INTEGER). Sem a vírgula, o SQLite leu nota INTEGER como parte do nome do tipo (ele aceita tipos com várias palavras, como DOUBLE PRECISION). O erro só aparece depois, quando alguém tenta usar a coluna que não existe:

CREATE TABLE avaliacoes (
    id         INTEGER,
    produto_id INTEGER
    nota       INTEGER
);

INSERT INTO avaliacoes (id, produto_id, nota) VALUES (1, 3, 5);

"A tabela avaliacoes não tem uma coluna chamada nota." Como consertar: apague a tabela (aula DROP TABLE), ponha a vírgula e crie de novo. E crie o hábito: depois de todo CREATE TABLE, confira com PRAGMA table_info ou .schema.

A tabela já existe
CREATE TABLE clientes (id INTEGER, nome TEXT);

O que diz: table clientes already exists, "a tabela clientes já existe". Como consertar: se você queria uma tabela nova, escolha outro nome. Se o roteiro pode rodar de novo, use CREATE TABLE IF NOT EXISTS. Se você quer trocar a tabela velha pela nova, apague a velha antes com DROP TABLE (com cuidado: os dados dela vão junto).

Duas colunas com o mesmo nome
CREATE TABLE avaliacoes (
    id         INTEGER,
    nota       INTEGER,
    comentario TEXT,
    nota       TEXT
);

O que diz: duplicate column name: nota, "nome de coluna repetido: nota". Numa tabela, cada coluna tem um nome só seu; senão, como o SELECT nota saberia qual das duas você quer? Como consertar: renomeie uma delas (nota_entrega, por exemplo) ou apague a repetida.

Nome com espaço ou começando por número
CREATE TABLE minhas avaliacoes (id INTEGER);

near "avaliacoes": syntax error: o SQLite pegou minhas como nome da tabela e não entendeu o que avaliacoes está fazendo ali. E com um número na frente:

CREATE TABLE 2026_vendas (id INTEGER);

unrecognized token: "2026_vendas", "símbolo não reconhecido". Um nome que começa por algarismo não é nome para o SQLite. Como consertar: minhas_avaliacoes e vendas_2026.

Esqueceu de fechar o parêntese
CREATE TABLE avaliacoes (
    id   INTEGER,
    nota INTEGER

No editor: incomplete input, "comando incompleto": o texto acabou com o parêntese ainda aberto. No terminal é diferente: o sqlite3 não dá erro, ele espera você terminar. O prompt muda de sqlite> para (x1...>, o jeito dele de avisar "tem 1 parêntese aberto, continue digitando":

$ sqlite3 loja.db
SQLite version 3.50.4 2025-07-30 19:33:53
Enter ".help" for usage hints.
sqlite> CREATE TABLE teste (id INTEGER
(x1...> );                         « fechou o parêntese: agora o comando roda
sqlite> .quit

Como consertar: feche o parêntese e ponha o ;. Se você ficou preso no (x1...> sem saber o que faltava, digite ); e Enter.

Mais valores que colunas no INSERT
CREATE TABLE avaliacoes (id INTEGER, nota INTEGER);

INSERT INTO avaliacoes VALUES (1, 5, 'Chegou rápido');

O que diz: table avaliacoes has 2 columns but 3 values were supplied, "a tabela tem 2 colunas, mas foram dados 3 valores". A tabela foi criada com duas colunas e só aceita duas. Como consertar: se faltou a coluna do comentário, ela tem de estar no CREATE TABLE (ou ser acrescentada com ALTER TABLE).


Nos outros bancos

O CREATE TABLE é do SQL padrão e funciona igual no MySQL, no PostgreSQL e no SQL Server: nome, parênteses, colunas separadas por vírgula. As diferenças estão nos tipos (aula Tipos de Dados) e no IF NOT EXISTS:

  • MySQL e PostgreSQL aceitam CREATE TABLE IF NOT EXISTS, e as duas documentações avisam a mesma pegadinha do SQLite: não há conferência de que a tabela existente tem a estrutura pedida. O PostgreSQL ainda emite um aviso (notice).
  • SQL Server não tem IF NOT EXISTS no CREATE TABLE. O costume lá é testar antes com a função OBJECT_ID (trecho ilustrativo, não roda no SQLite):
IF OBJECT_ID(N'avaliacoes', N'U') IS NULL
    CREATE TABLE avaliacoes (id INT, nota INT);

Referência rápida

EscritaO que faz
CREATE TABLE nome (col1 TIPO, col2 TIPO);Cria a tabela nome com essas colunas, vazia
CREATE TABLE IF NOT EXISTS nome (…);Cria só se não existir; se existir, não faz nada (não compara as colunas)
col TIPO NOT NULL DEFAULT 0Coluna com restrições depois do tipo
SELECT sql FROM sqlite_schema WHERE name = 'nome';Mostra o CREATE TABLE de uma tabela
PRAGMA table_info(nome);Lista as colunas, os tipos e as regras
.tables / .schema nomeO mesmo, no terminal sqlite3 (não no editor)
Mensagem do SQLiteQuer dizer
table X already existsJá existe uma tabela com esse nome
near ")": syntax errorQuase sempre: vírgula sobrando antes do )
duplicate column name: XDuas colunas com o mesmo nome
near "order": syntax errorUsou uma palavra reservada como nome
unrecognized token: "2026_vendas"Nome que começa por número
incomplete inputFaltou fechar o parêntese (no editor)
table X has no column named YA coluna não existe: confira o CREATE TABLE (vírgula faltando?)

Exercícios

1. Complete o comando

Complete para criar a tabela marcas com as colunas id (inteiro) e nome (texto):

marcas (id , nome TEXT);

2. Só se não existir

Complete para que o comando não dê erro se a tabela já existir:

CREATE TABLE marcas (id INTEGER, nome TEXT);

3. Qual destes comandos dá near ")": syntax error?

4. A Ana rodou CREATE TABLE IF NOT EXISTS clientes (codigo INTEGER); no banco da loja, que já tem a tabela clientes. O que acontece?

5. Qual é o melhor nome para uma tabela que guarda as entregas da loja?

6. Depois de CREATE TABLE t (a INTEGER b TEXT); (sem vírgula), quantas colunas a tabela t tem?

Missão final: a tabela de avaliações

Missão: crie a tabela avaliacoes com quatro colunas, nesta ordem: id (inteiro), produto_id (inteiro), nota (inteiro) e comentario (texto). Os dois INSERT e o SELECT já estão prontos embaixo; só falta o CREATE TABLE no lugar do comentário.

-- escreva aqui o CREATE TABLE avaliacoes

INSERT INTO avaliacoes (id, produto_id, nota, comentario)
VALUES (1, 1, 5, 'Folhas grossas, a caneta não atravessa');

INSERT INTO avaliacoes (id, produto_id, nota, comentario)
VALUES (2, 5, 3, 'Bonita, mas a alça é fina');

SELECT * FROM avaliacoes;
CREATE TABLE avaliacoes (
    id         INTEGER,
    produto_id INTEGER,
    nota       INTEGER,
    comentario TEXT
);

INSERT INTO avaliacoes (id, produto_id, nota, comentario)
VALUES (1, 1, 5, 'Folhas grossas, a caneta não atravessa');

INSERT INTO avaliacoes (id, produto_id, nota, comentario)
VALUES (2, 5, 3, 'Bonita, mas a alça é fina');

SELECT * FROM avaliacoes;

Se a sua tabela funcionou, experimente juntar as avaliações com os nomes dos produtos (produto 1 é o Caderno Pautado 96 folhas, o 5 é a Mochila Escolar Azul): isso é um JOIN, e você já sabe fazer (aula INNER JOIN).


Resumo

  • CREATE TABLE nome (coluna TIPO, …); cria uma tabela nova, vazia. As colunas vão entre parênteses, separadas por vírgula, cada uma com nome e tipo.
  • Os tipos do dia a dia: INTEGER (inteiro), REAL (com decimais) e TEXT (texto, e também datas no formato AAAA-MM-DD).
  • Confira o que criou: sqlite_schema e PRAGMA table_info no editor; .tables e .schema no terminal.
  • Nomes em minúsculas, sem espaço nem acento, começando por letra, e nada de palavra reservada como order.
  • IF NOT EXISTS evita o erro table X already exists, mas não compara as colunas: se a tabela existe, ele simplesmente não faz nada.
  • Vírgula sobrando dá near ")": syntax error; vírgula faltando não dá erro e junta duas colunas numa. Depois de criar, confira sempre.