Se você precisar encontrar linhas que contenham letras minúsculas no SQL Server, tente uma das seguintes opções.
Dados de amostra
Suponha que temos uma tabela com os seguintes dados:
SELECT c1 FROM t1;
Resultado:
+----------------+ | c1 | |----------------| | CAFÉ | | Café | | café | | 1café | | eCafé | | James Bond 007 | | JB 007 | | 007 | | NULL | | | | É | | É 123 | | é | | é 123 | | ø | | Ø | +----------------+
Podemos usar os seguintes métodos para retornar as linhas que contêm letras minúsculas.
Opção 1:Compare com o UPPER()
Cadeia
Podemos usar o
UPPER()
função para comparar o valor original com seu equivalente em maiúsculas:SELECT * FROM t1
WHERE UPPER(c1) COLLATE Latin1_General_CS_AS <> c1;
Resultado:
+----------------+ | c1 | |----------------| | Café | | café | | 1café | | eCafé | | James Bond 007 | | é | | é 123 | | ø | +----------------+
Usando o diferente de (
<>
) operador (você pode usar alternativamente !=
em vez de <>
se preferir), apenas retornamos as linhas que são diferentes de seus equivalentes em maiúsculas. A razão pela qual fazemos isso é porque, se um valor é o mesmo que seu equivalente em maiúsculas, então já era em maiúsculas (e não queremos devolvê-lo). Também usamos
COLLATE Latin1_General_CS_AS
para especificar explicitamente um agrupamento que diferencia maiúsculas de minúsculas (e diferencia acentos). Sem isso, você pode obter resultados inesperados, dependendo do agrupamento usado em seu sistema. Opção 2:comparar com os caracteres reais
Alternativamente, podemos usar o
LIKE
operador e especifique os caracteres minúsculos reais que queremos corresponder:SELECT * FROM t1
WHERE c1 LIKE '%[abcdefghijklmnopqrstuvwxyz]%'
COLLATE Latin1_General_CS_AS;
Resultado:
+----------------+ | c1 | |----------------| | Café | | café | | 1café | | eCafé | | James Bond 007 | +----------------+
Nesse caso, menos linhas são retornadas do que no exemplo anterior. Isso ocorre porque eu não especifiquei caracteres como
é
e ø
, que foram retornados no exemplo anterior. Embora uma linha contenha é
, essa linha só foi retornada porque também contém outros caracteres minúsculos que correspondem. Portanto, este exemplo é mais limitado que o anterior, mas fornece mais controle sobre os caracteres que você deseja corresponder.
Opção 3:comparar com um intervalo de caracteres
Alternativamente, podemos especificar o intervalo de caracteres que queremos corresponder:
SELECT * FROM t1
WHERE c1 LIKE '%[a-z]%'
COLLATE Latin1_General_100_BIN2;
Resultado:
+----------------+ | c1 | |----------------| | Café | | café | | 1café | | eCafé | | James Bond 007 | +----------------+
Nesse caso, usei um agrupamento binário (
Latin1_General_100_BIN2
). Eu fiz isso porque os agrupamentos binários classificam cada caso separadamente (assim:AB....YZ...ab...yz
). Outros agrupamentos tendem a misturar as letras maiúsculas e minúsculas (assim:
AaBb...YyZz
), que, portanto, corresponderia a caracteres maiúsculos e minúsculos. Opção 4:encontre a primeira instância de um caractere minúsculo
Outra maneira de fazer isso é usar o
PATINDEX()
função:SELECT * FROM t1
WHERE PATINDEX('%[abcdefghijklmnopqrstuvwxyz]%', c1
COLLATE Latin1_General_CS_AS) > 0;
Resultado:
+----------------+ | c1 | |----------------| | Café | | café | | 1café | | eCafé | | James Bond 007 | +----------------+
Neste exemplo, especificamos os caracteres exatos que queremos corresponder e, portanto, não obtivemos as linhas com caracteres como
é
e ø
(diferente daquele que também contém outros caracteres que foram correspondidos). Um benefício desta técnica é que podemos usá-la para ignorar o primeiro caractere (ou número especificado de caracteres) se assim o desejarmos:
SELECT * FROM t1
WHERE PATINDEX('%[abcdefghijklmnopqrstuvwxyz]%', c1
COLLATE Latin1_General_CS_AS) > 1;
Resultado:
+----------------+ | c1 | |----------------| | Café | | 1café | | James Bond 007 | +----------------+
Portanto, podemos retornar todas as linhas que contêm caracteres minúsculos, mas onde o primeiro caractere não é minúsculo.
Isso ocorre porque
PATINDEX()
retorna a posição inicial da primeira ocorrência do padrão (no nosso caso, o padrão é uma lista de caracteres minúsculos). Se a posição inicial da primeira ocorrência for maior que 1, o primeiro caractere não estará em nossa lista de caracteres minúsculos. Embora essa técnica possa ser usada para ignorar o primeiro caractere sendo maiúsculo, não exclui que o primeiro caractere possa ser outro caractere, como um número. Podemos ver isso na segunda linha, que contém
1café
. Opção 5:encontrar a primeira instância com base em um intervalo
Também podemos usar
PATINDEX()
com um intervalo:SELECT * FROM t1
WHERE PATINDEX('%[a-z]%', c1
COLLATE Latin1_General_100_BIN2) > 1;
Resultado:
+----------------+ | c1 | |----------------| | Café | | 1café | | James Bond 007 | +----------------+
Usei novamente um agrupamento binário (como no outro exemplo de intervalo).