2010-05-26 20 views
11

Nel mio database ho molti utenti che hanno sbagliato a digitare il loro indirizzo e-mail. Ciò a sua volta causa il mio postfix per far rimbalzare un sacco di mail quando si invia la newsletter.
I moduli includono (ma non sono limitati a) "yaho.com", "yahho .com", ecc.
Molto fastidioso!Mysql: come aggiornare "dominio.com" in "[email protected]"

Quindi ho cercato di aggiornare quei record al valore corretto.
Dopo aver eseguito select email from users where email like '%@yaho%' and email not like '%yahoo%'; e ottenuto l'elenco, sono bloccato perché non so come aggiornare solo la parte yaho. Ho bisogno che lo username sia lasciato intatto.

così ho pensato che sarebbe solo il dump del database e utilizzare vim per sostituire, ma non può sfuggire il simbolo @ ..

BTW, come faccio a selezionare tutti gli indirizzi e-mail scritte in CAPS? select upper(email) from users; trasformerebbe semplicemente tutto in CAPS, mentre dovevo solo trovare le mail di CAPS già scritte.

+3

Se avete bisogno di indirizzi e-mail validi, è possibile aggiungere una verifica e-mail al momento della registrazione? Non puoi garantire che la modifica di [email protected] a [email protected] raggiunga effettivamente il tuo utente registrato, né che non produrrà nemmeno un rimbalzo. –

+0

In effetti hai ragione, ho anche pensato che qualsiasi persona sana di mente dovrebbe aggiungere la convalida. Ma sono solo il sysadmin qui e ho pensato di affrontare la situazione dalla mia parte. Dovrà presentare un bug o smth. – w00t

risposta

27

si consiglia di provare qualcosa di simile al seguente:. caso

UPDATE users 
SET  email = CONCAT(LEFT(email, INSTR(email, '@')), 'yahoo.com') 
WHERE email LIKE '%@yaho.com%'; 

test:

CREATE TABLE users (email varchar(50)); 

INSERT INTO users VALUES ('[email protected]'); 
INSERT INTO users VALUES ('[email protected]'); 
INSERT INTO users VALUES ('[email protected]'); 


UPDATE users 
SET  email = CONCAT(LEFT(email, INSTR(email, '@')), 'yahoo.com') 
WHERE email LIKE '%@yaho.com%'; 

Query OK, 1 row affected (0.00 sec) 
Rows matched: 1 Changed: 1 Warnings: 0 


SELECT * FROM users; 
+-----------------+ 
| email   | 
+-----------------+ 
| [email protected] | 
| [email protected] | 
| [email protected] | 
+-----------------+ 
3 rows in set (0.00 sec) 

Per rispondere alla tua seconda domanda, probabilmente è necessario use a case sensitive collation come il latin1_general_cs:

SELECT * FROM users WHERE email COLLATE latin1_general_cs = UPPER(email); 

Test case:

INSERT INTO users VALUES ('[email protected]'); 


SELECT * FROM users; 
+-----------------+ 
| email   | 
+-----------------+ 
| [email protected] | 
| [email protected] | 
| [email protected] | 
| [email protected] | 
+-----------------+ 
4 rows in set (0.00 sec) 


SELECT * FROM users WHERE email COLLATE latin1_general_cs = UPPER(email); 
+-----------------+ 
| email   | 
+-----------------+ 
| [email protected] | 
+-----------------+ 
1 row in set (0.00 sec) 
+1

Ottimo esempio! Ha funzionato senza problemi. Una cosa però, il database è UTF8 quindi non posso usare le regole di confronto latin1. Ma non è un grosso problema, la SELECT non è vitale, ho appena aggiornato tutto in minuscolo. Grazie! – w00t

+0

Sto ancora tornando a questa risposta anni dopo. –

+0

Sto provando a mettere @ in un varchar. Ma si dice extranoues ... Come inserire gli indirizzi e-mail in mysql? – Lealo

1

Si potrebbe provare a utilizzare INSTR insieme a SUBSTR o LEFT per ottenere la parte prima del simbolo "@", forse.

Qualcosa come SELECT LEFT("[email protected]",INSTR("[email protected]","@")-1); sembra funzionare.

+0

Sì, anche questo funziona. – w00t

2

Per affrontare la seconda domanda (circa l'individuazione e-mail scritte in maiuscolo), qualcosa di simile potrebbe essere utile:

select email from users where upper(email) = email 

(mi perdoni se la sintassi non è proprio corretto, dal momento che io sono abituato a DB2 . l'idea è quella di confrontare l'indirizzo di posta elettronica direttamente con la versione in maiuscolo)

+0

@Syntactic: nota che il set di caratteri e le regole di confronto predefiniti in MySQL non fanno distinzione tra maiuscole e minuscole per impostazione predefinita. [Fonte] (http://dev.mysql.com/doc/refman/5.0/en/case-sensitivity.html) –

+0

@Daniel Vassallo Buon punto. Imparare qualcosa di nuovo ogni giorno. – Syntactic

+0

Oh penso di capire cosa intendi. Ma invece di trovare mail MAIUSC, restituisce tutte le mail in maiuscole .. circa 50.000 di esse :)) Abbastanza corretto con la custodia insensibile, non c'è alcun problema con l'invio di mail o altro, è solo che mi ha infastidito gli occhi. – w00t

1

Per la prima domanda, vorrei scegliere qualcosa di simile

UPDATE users 
SET email = INSERT(email,INSTR(email,'@'), LENGTH(email), '@yahoo.com') 
WHERE email LIKE '%@yaho.com' 

Solo per il gusto di essere accurato, questo è sicuro multi-byte anche se ho usato LENGTH. Tutto ciò che serve è che il terzo argomento di INSERT sia largo almeno quanto la fine della sottostringa.

risposta di sintattica di trovare l'e-mail tutto in maiuscolo è una buona risposta. Forse l'esecuzione leggermente più veloce, anche se si sarebbe probabilmente non notare la differenza, è

SELECT email FROM users WHERE BINARY(email) NOT REGEXP '[a-z]' 

Aggiornamento: BINARY(email) è necessario per forzare corrispondenza tra maiuscole e minuscole.

+1

Penso che sia necessario racchiudere '@' nelle virgolette singole nella funzione 'INSTR()' altrimenti restituirà 'NULL'. Suppongo anche che la tua ultima query dovrebbe apparire come 'Dagli utenti DOVE email NON REGEXP ...'. –

+1

Infatti, '@' aveva bisogno di virgolette singole perché restituiva 'NULL'. Ha funzionato dopo. La seconda query corrisponde solo alle e-mail che sono fatte di numeri o + - ma non alfabetici. – w00t

+0

Grazie per le correzioni! –

0
UPDATE contacts SET email = REPLACE(email, SUBSTRING_INDEX(email, '@', -1), 'domain.com') 
Problemi correlati