🙏 Precisamos da sua ajuda! O SQLtest.online não tem anúncios e vive só de doações. Até uma pequena quantia ajuda. Doar agora →
Código SQL copiado para a área de transferência

Maiúsculas e Minúsculas no SQL em Diferentes Bancos

Lição 1.9 · Tempo de leitura: ~9 min

A diferença entre maiúsculas e minúsculas no SQL existe em três níveis: palavras-chave, nomes de objetos e dados. Palavras-chave como SELECT não diferenciam maiúsculas em nenhum banco de dados, mas se Customer e customer são a mesma tabela depende do banco, das aspas e às vezes até do sistema operacional. Nesta lição você vai conhecer as regras de cada banco popular, a armadilha clássica dos nomes entre aspas, como as comparações de strings tratam a caixa e um estilo de nomes que evita todos esses problemas.

Na lição 1.8 você viu que os bancos seguem o padrão SQL com seus próprios dialetos. A caixa das letras é uma das diferenças mais visíveis: uma consulta que funciona no SQL Server pode falhar no PostgreSQL com relation "Customer" does not exist, e uma consulta escrita num notebook com Windows pode falhar num servidor Linux.

Conhecer as regras antes das primeiras consultas economiza horas procurando uma tabela que "com certeza existe".

Maiúsculas e minúsculas no SQL: palavras-chave ignoram a caixa em todo lugar, o nome sem aspas Customer vira customer no PostgreSQL e CUSTOMER no Oracle e no Firebird, e "Customer" entre aspas mantém a caixa

Três Níveis de Caixa no SQL

Quando alguém pergunta "o SQL diferencia maiúsculas e minúsculas?", pode estar falando de três coisas diferentes:

  1. Palavras-chave e nomes de funções: SELECT, select, COUNT, count.
  2. Identificadores: os nomes de bancos, tabelas, colunas e aliases, que você conheceu na lição 1.7.
  3. Dados: se a string 'abc' é igual a 'ABC' numa condição WHERE.

Cada nível tem suas próprias regras, então vamos vê-los um por um.


Palavras-chave do SQL Não Diferenciam Maiúsculas

Palavras-chave e nomes de funções internas podem ser escritos em qualquer caixa em todos os bancos:

sElEcT title
FrOm film
WhErE film_id = 1;

Resultado: ACADEMY DINOSAUR. MySQL, PostgreSQL, SQL Server, Oracle, Firebird e SQLite executam a consulta com qualquer mistura de caixas.

Escrever palavras-chave em MAIÚSCULAS é só uma convenção: separa a linguagem dos nomes de tabelas e colunas e torna consultas longas mais fáceis de ler. Este curso escreve palavras-chave em maiúsculas e nomes em minúsculas, e a maioria dos guias de estilo recomenda o mesmo.


Identificadores sem Aspas: Cada Banco Converte de um Jeito

O padrão SQL diz que um nome sem aspas é convertido para maiúsculas, então customer, Customer e CUSTOMER são o mesmo nome. Os bancos implementam essa ideia de formas diferentes.

PostgreSQL: Nomes Viram Minúsculas

O PostgreSQL converte todo nome sem aspas para minúsculas, o contrário do padrão:

SELECT Model, AIRCRAFT_CODE
FROM Aircrafts
WHERE aircraft_code = '773';

Resultado: Boeing 777-300. A tabela está guardada como aircrafts, e os cabeçalhos das colunas voltam como model e aircraft_code.

Os aliases também são convertidos: SELECT model AS TotalModel devolve uma coluna chamada totalmodel. A caixa que você digitou desaparece assim que a consulta é analisada.

Oracle e Firebird: Nomes Viram Maiúsculas

O Oracle e o Firebird seguem o padrão e convertem nomes sem aspas para maiúsculas:

select first_name, Last_Name
from Employee
where emp_no = 2;

Resultado no Firebird: Robert Nelson, com os cabeçalhos FIRST_NAME e LAST_NAME. O mesmo acontece no Oracle com hr.Employees.

Por isso as ferramentas mostram as tabelas do Oracle e do Firebird em maiúsculas: EMPLOYEES, EMPLOYEE.

SQL Server: Quem Decide É a Collation

O SQL Server não converte os nomes. Ele guarda a caixa usada no CREATE TABLE e compara os nomes pela collation do banco: o conjunto de regras de comparação de texto.

A collation padrão, como SQL_Latin1_General_CP1_CI_AS, não diferencia maiúsculas (CI), então estes nomes são iguais:

select name, listprice
from PRODUCT
where productid = 680;

Resultado: HL Road Frame - Black, 58. No AdventureWorks os cabeçalhos voltam como você os digitou: name e listprice.

Um banco criado com uma collation que diferencia maiúsculas (_CS_) trata Product e PRODUCT como nomes diferentes. Esses bancos são raros, mas existem, então verifique DATABASEPROPERTYEX(DB_NAME(), 'Collation') antes de supor qualquer coisa.

MySQL e MariaDB: Nomes de Tabelas Seguem o Sistema Operacional

No MySQL e no MariaDB um banco é uma pasta e uma tabela é um arquivo, então as regras de caixa para bancos e tabelas vêm do sistema de arquivos. Quem as controla é a configuração lower_case_table_names:

ValorPadrão noNomes de tabelas
0Linuxguardados como escritos, comparados diferenciando maiúsculas
1Windowsguardados em minúsculas, comparados sem diferenciar
2macOSguardados como escritos, comparados sem diferenciar

A sandbox deste curso roda em Linux, então a caixa errada no nome de uma tabela é um erro:

SELECT title
FROM FILM
WHERE film_id = 1;

Resultado: Table 'sakila.FILM' doesn't exist. Com FROM film a consulta funciona.

No Linux, Customer e customer podem ser até duas tabelas diferentes no mesmo banco. Os aliases de tabela seguem a mesma regra: FROM film F com WHERE f.film_id = 1 falha com Unknown column 'f.title'.

Já os nomes de colunas não diferenciam maiúsculas no MySQL e no MariaDB em nenhum sistema: SELECT TITLE, Film_ID FROM film funciona.

SQLite e DuckDB: Nunca Diferenciam

O SQLite e o DuckDB comparam nomes sem diferenciar maiúsculas, mesmo entre aspas, e lembram a caixa usada na criação do objeto:

CREATE TEMP TABLE "Customer" ("FullName" text);
INSERT INTO "Customer" VALUES ('Orlando Gee');

SELECT fullname
FROM CUSTOMER;

Resultado no SQLite e no DuckDB: Orlando Gee sob o cabeçalho FullName. Uma segunda tabela chamada customer não pode ser criada: o nome já está ocupado.


Identificadores entre Aspas Mantêm a Caixa

As aspas transformam um nome num identificador delimitado: o banco o usa exatamente como foi escrito, com caixa, espaços e palavras reservadas. O padrão usa aspas duplas; o MySQL usa crases, e o SQL Server também aceita colchetes:

BancoNome entre aspas
PostgreSQL, Oracle, Firebird, SQLite, DuckDB"Customer"
MySQL, MariaDB`Customer`
SQL Server[Customer] ou "Customer"

No PostgreSQL, no Oracle e no Firebird um nome entre aspas diferencia maiúsculas. Essa é a origem do erro de caixa mais comum.

A Armadilha "Customer" no PostgreSQL

Muitas ferramentas, ORMs e scripts de migração criam tabelas com nomes entre aspas. Veja o que acontece depois:

CREATE TEMP TABLE "Customer" ("CustomerID" int, "FullName" text);
INSERT INTO "Customer" VALUES (1, 'Orlando Gee');

SELECT *
FROM Customer;

Resultado: relation "customer" does not exist. O Customer sem aspas virou customer, mas a tabela se chama Customer.

Se um nome foi criado com aspas e letras maiúsculas, toda consulta também precisa colocá-lo entre aspas, exatamente com a mesma caixa:

SELECT "FullName"
FROM "Customer";

Resultado: Orlando Gee. Sem aspas, SELECT FullName falha com column "fullname" does not exist.

O PostgreSQL até dá uma dica: Perhaps you meant to reference the column "Customer.FullName". O Oracle e o Firebird têm o problema espelhado: hr."employees" falha, porque a tabela está guardada como EMPLOYEES.

Aspas Duplas no MySQL São uma String

No MySQL e no MariaDB as aspas duplas nem são um nome: por padrão elas marcam uma string, como as aspas simples:

SELECT "title"
FROM film
WHERE film_id = 1;

Resultado: a palavra title, e não o título do filme. O MySQL devolve a constante de texto 'title' para cada linha.

A consulta não falha, então o erro passa despercebido com facilidade. Use crases para nomes no MySQL ou ative o modo ANSI_QUOTES para que as aspas duplas sigam o padrão.


Caixa nos Dados: Comparando Strings

O terceiro nível são os próprios dados. Se 'abc' = 'ABC' é verdadeiro depende do banco e da collation da coluna:

Banco'abc' = 'ABC' por padrãoLIKEBusca sem diferenciar maiúsculas
MySQL, MariaDBverdadeironão diferenciajá é o padrão; BINARY ou collation _bin para exata
SQL Serververdadeiro (collation CI)não diferenciajá é o padrão; COLLATE ..._CS_AS para exata
PostgreSQLfalsodiferenciaILIKE, LOWER()
OraclefalsodiferenciaUPPER(), LOWER()
FirebirdfalsodiferenciaCONTAINING, UPPER()
SQLitefalsonão diferencia (letras latinas)COLLATE NOCASE, LOWER()
DuckDBfalsodiferenciaILIKE, COLLATE NOCASE

A mesma condição dá resultados diferentes. No PostgreSQL o banco Bookings não tem a cidade 'moscow':

SELECT COUNT(*)
FROM airports
WHERE city = 'moscow';

Resultado: 0. Com WHERE lower(city) = 'moscow' ou WHERE city ILIKE 'moscow' a consulta encontra 3 aeroportos de Moscou.

No MySQL a consulta parecida no Sakila encontra os atores de primeira:

SELECT COUNT(*)
FROM actor
WHERE last_name = 'davis';

Resultado: 3, embora os sobrenomes estejam guardados como DAVIS. Com WHERE BINARY last_name = 'davis' o resultado é 0.

Por isso uma consulta levada do MySQL ou do SQL Server para o PostgreSQL pode devolver menos linhas sem nenhum aviso. Quando a caixa dos dados não importa, diga isso na consulta: compare LOWER(coluna) com um valor em minúsculas. As collations fazem muito mais do que tratar a caixa: também definem a ordenação e os acentos, e terão uma lição própria mais adiante no curso.


Caixa em Cada Banco de Dados

BancoNomes sem aspasNomes entre aspas'abc' = 'ABC'
PostgreSQLminúsculasdiferenciam maiúsculasfalso
Oraclemaiúsculasdiferenciam maiúsculasfalso
Firebirdmaiúsculasdiferenciam maiúsculasfalso
SQL Servercomo escritos, comparados pela collation (geralmente sem diferenciar)o mesmo que sem aspasverdadeiro com collation CI
MySQL, MariaDBtabelas e bancos: dependem de lower_case_table_names (diferenciam no Linux); colunas: não diferenciamo mesmo que sem aspasverdadeiro
SQLitenão diferenciamnão diferenciamfalso
DuckDBnão diferenciamnão diferenciamfalso

Palavras-chave e nomes de funções não diferenciam maiúsculas em nenhum deles.


Regras de Nomes que Evitam Problemas de Caixa

Você não precisa decorar a tabela inteira se seguir algumas regras:

  • Dê nomes a tabelas e colunas em minúsculas com sublinhados: customer_order, total_amount. Esses nomes significam o mesmo em todo banco e nunca precisam de aspas.
  • Não crie nomes entre aspas com maiúsculas ou espaços. Se uma ferramenta os criou, coloque-os entre aspas em todo lugar, com a caixa exata.
  • Escreva cada nome sempre com a mesma caixa, mesmo onde o banco perdoa: assim uma consulta escrita no Windows ou no SQL Server também funcionará no Linux e no PostgreSQL.
  • Escreva as palavras-chave em maiúsculas pela legibilidade; para o banco tanto faz.
  • Em condições de texto, decida se a caixa importa e deixe isso explícito com LOWER(), UPPER() ou ILIKE, em vez de depender da collation padrão.

Mais conselhos sobre nomes estão reunidos na lição 10.1. Com essas regras em mente você está pronto para o próximo módulo, onde começa a consultar dados com SELECT.


Principais conclusões:

  • Palavras-chave e nomes de funções do SQL não diferenciam maiúsculas em nenhum banco; as maiúsculas são uma convenção de estilo.
  • Nomes sem aspas são convertidos para minúsculas no PostgreSQL e para maiúsculas no Oracle e no Firebird; o SQL Server os compara pela collation do banco.
  • No MySQL e no MariaDB os nomes de tabelas diferenciam maiúsculas no Linux (lower_case_table_names = 0), e os de colunas não.
  • Um nome entre aspas mantém a caixa: uma tabela criada como "Customer" no PostgreSQL sempre deve ser escrita como "Customer".
  • 'abc' = 'ABC' é verdadeiro por padrão no MySQL e no SQL Server e falso no PostgreSQL, Oracle, Firebird, SQLite e DuckDB.
  • Nomes em snake_case minúsculo e sem aspas funcionam igual em todo lugar.

Perguntas Frequentes

O SQL diferencia maiúsculas e minúsculas?

As palavras-chave não: SELECT e select são iguais em todo lugar. Os nomes de tabelas e colunas dependem do banco: PostgreSQL, Oracle e Firebird convertem nomes sem aspas para uma única caixa, o SQL Server usa a collation e os nomes de tabelas do MySQL seguem o sistema operacional. As comparações de strings dependem da collation dos dados.

Os nomes de tabelas diferenciam maiúsculas no MySQL?

No Linux, sim: com o padrão lower_case_table_names = 0, FILM e film são tabelas diferentes. No Windows e no macOS são a mesma. Os nomes de colunas não diferenciam maiúsculas em nenhum sistema, então, por segurança, dê nomes de tabelas em minúsculas.

Por que o PostgreSQL diz que a relation não existe se a tabela está lá?

Muito provavelmente a tabela foi criada com um nome entre aspas e com maiúsculas, como "Customer". O PostgreSQL converte o Customer sem aspas da sua consulta para customer, que é outro nome. Escreva o nome entre aspas duplas com a caixa exata: FROM "Customer".

Como fazer uma busca sem diferenciar maiúsculas no PostgreSQL?

Use ILIKE em vez de LIKE (WHERE city ILIKE 'moscow') ou compare valores em minúsculas: WHERE lower(city) = 'moscow'. Para buscas frequentes, um índice em lower(city) torna a segunda variante rápida.

As palavras-chave do SQL devem ser escritas em maiúsculas?

Para o banco tanto faz, então é questão de estilo. Palavras-chave em maiúsculas e nomes em minúsculas é a convenção mais comum, porque deixa a estrutura da consulta fácil de ver. O importante é manter a consistência dentro do projeto.