Consulta de caracteres especiais em uma coluna string que possui endereços de email
A resposta vai depender muito do seu SGBD, pois a maioria das soluções utiliza funções de manipulação de strings e essas são implementadas livremente (não fazem parte do padrão SQL) pelos fornecedores da linguagem SQL suportada pelo SGBD.
Sabendo disso, não vai existir uma consulta que funcione em todos.
Vou explicar a lógica por trás das implementações, assim você pode solucionar o problema em qualquer SGBD, mesmo que não exista uma solução listada para o seu SGBD.
Desejamos encontrar uma string que contém caracteres especiais dentro de uma coluna que possui endereços de e-mails. Em linhas gerais o seu problema se resume à:
<parte1>@<parte2>
E desejamos encontrar caracteres especiais em endereços de e-mail que estão na parte1
.
Para resolver este problema, basta encontrar o caractere @ na string.
Uma vez que encontrar o caractere arroba, procurar caracteres especiais do início da string (índice 0) até o índex do caractere arroba (índice N).
Como N é variável, vamos usar uma função auxiliar para localizar o índice do caractere arroba, é essa função que vai determinar o índice N. Cada fornecedor de banco de dados implementa alguma função que possui esta finalidade, então basta procurar na documentação de funções de manipulação de string, que existirá uma função com esta finalidade.
Segue um exemplo:
email@exemplo.com
^ --> verificar caracteres especiais até esta posição.
Vamos a um exemplo prático
Vamos supor que você possui o seguinte esquema:
CREATE TABLE usuario (
id INTEGER PRIMARY KEY,
nome VARCHAR(1),
email VARCHAR(256)
);
E possui os seguintes dados inseridos na tabela:
INSERT INTO usuario(id, nome, email) VALUES (1,'a','a@a.com.br');
INSERT INTO usuario(id, nome, email) VALUES (2,'b','!@a.com.br');
INSERT INTO usuario(id, nome, email) VALUES (3,'c','a1a@a.com.br');
INSERT INTO usuario(id, nome, email) VALUES (4,'d','a-a@a.com.br');
INSERT INTO usuario(id, nome, email) VALUES (5,'e','a.a@a.com.br');
INSERT INTO usuario(id, nome, email) VALUES (6,'f','a$a@a.com.br');
INSERT INTO usuario(id, nome, email) VALUES (7,'g','a&a@a.com.br');
INSERT INTO usuario(id, nome, email) VALUES (8,'h','a*a@a.com.br');
Se deseja encontrar os caracteres especiais ponto ("."), vírgula (",") e traço ("-") então podemos criar uma expressão regular que representa esta regra da seguinte forma:
'[\.\,\-]'
Repare que acima estou usando o caractere contra-barra ("") antes de cada caractere, isso torna um caractere literal. Ou seja estou deixando explicito que desejo o caractere ".", "," ou "-".
Pois o ponto(".") e traço ("-") em uma expressão regular possuem semântica de operadores.
Uma solução em Postgres (plpg-sql)
Uma consulta que resolve este problema no SGBD Postgres seria:
SELECT * FROM usuario WHERE SPLIT_PART(email,'@', 1) ~ '[\.\,\-]';
para esta implementação a função SPLIT_PART vai encontrar a posição do caractere arroba, e retornar uma substring é nesta string que eu vou procurar se existem caracteres especiais.
O operador ˜
é um operador para comparação de expressões regulares
Uma solução em Mysql
SELECT * FROM usuario WHERE SUBSTRING_INDEX(email,'@',1) REGEXP '[\.\,\-]';
Nesta solução estamos usando a função SUBSTRING_INDEX que vai encontrar o caractere @ na string.
O regexp é um operador de comparação de expressões regulares.
Uma solução em Sqlserver (t-sql)
SELECT * FROM usuario WHERE substring(email, 0, CHARINDEX('@',email)) like '%[\.\,\-]%'
Para esta solução estou usando a função substring em combinação com a função charindex
Uma solução em Oracle (pl-sql)
SELECT * FROM usuario WHERE REGEXP_LIKE(SUBSTR(email,0,INSTR(email,'@')),'[\,\.\-]')
Nesta solução utilizei uma combinação das funções regexp_like use esta função em uma cláusula where para fazer a correspondência de expressões regulares em uma string. substr e instr