2010-05-26 32 views
11

Trong cơ sở dữ liệu của tôi, tôi có rất nhiều người dùng đã sai chính tả địa chỉ email của họ. Điều này lần lượt gây ra postfix của tôi để trả lại rất nhiều thư khi gửi bản tin.
Các biểu mẫu bao gồm (nhưng không giới hạn) "yaho.com", "yahho .com", v.v.
Rất khó chịu!Mysql-cách cập nhật "domain.com" trong "[email protected]"

Vì vậy, tôi đã cố cập nhật những bản ghi đó với giá trị chính xác.
Sau khi thực hiện select email from users where email like '%@yaho%' and email not like '%yahoo%'; và nhận danh sách, tôi bị kẹt vì tôi không biết cách cập nhật chỉ phần yaho. Tôi cần tên người dùng còn nguyên vẹn.

Vì vậy, tôi nghĩ rằng tôi sẽ chỉ đổ cơ sở dữ liệu và sử dụng vim để thay thế, nhưng tôi không thể thoát khỏi biểu tượng @ ..

BTW, làm thế nào để chọn tất cả các địa chỉ email viết bằng CAPS? select upper(email) from users; sẽ biến tất cả mọi thứ thành CAPS, trong khi tôi chỉ cần tìm ra các thư đã được viết sẵn trong CAPS.

+3

Nếu bạn yêu cầu địa chỉ e-mail hợp lệ, bạn có thể thêm xác minh e-mail khi đăng ký không? Bạn không thể đảm bảo rằng việc thay đổi [email protected] thành [email protected] sẽ thực sự tiếp cận được người dùng đã đăng ký của bạn, cũng không phải là nó cũng sẽ không tạo ra thư bị trả lại. –

+0

Thực ra bạn đúng, tôi cũng nghĩ rằng bất kỳ người lành mạnh nào cũng nên thêm tính hợp lệ. Nhưng tôi chỉ là sysadmin ở đây và tôi nghĩ để giải quyết tình hình từ phía tôi. Sẽ phải gửi một lỗi hoặc smth. – w00t

Trả lời

27

Bạn có thể muốn thử một cái gì đó như sau:. trường hợp

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) 

Để trả lời câu hỏi thứ hai của bạn, bạn có thể cần phải use a case sensitive collation như latin1_general_cs:

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

trường hợp thử nghiệm:

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

Ví dụ tuyệt vời! Làm việc mà không có vấn đề gì. Một điều mặc dù, cơ sở dữ liệu là UTF8 vì vậy tôi không thể sử dụng collations latin1. Nhưng không phải là một vấn đề lớn, SELECT không quan trọng, tôi chỉ cập nhật mọi thứ thành chữ thường. Cảm ơn bạn! – w00t

+0

Tôi vẫn quay trở lại câu trả lời này năm sau đó. –

+0

Tôi đang cố gắng để đặt @ trong một varchar. Nhưng là nói extranoues ... Làm thế nào để nhập địa chỉ email trong mysql? – Lealo

1

Bạn có thể thử sử dụng INSTR cùng với SUBSTR hoặc LEFT để nhận một phần trước biểu tượng "@".

Có điều gì đó giống như SELECT LEFT("[email protected]",INSTR("[email protected]","@")-1); dường như hoạt động.

+0

Vâng, điều này cũng hoạt động. – w00t

2

Để giải quyết câu hỏi thứ hai của bạn (về việc tìm kiếm các email viết bằng mũ), một cái gì đó như thế này có thể hữu ích:

select email from users where upper(email) = email 

(Hãy tha thứ cho tôi nếu cú ​​pháp là không chính xác đúng, vì tôi đang sử dụng để DB2 . ý tưởng là để so sánh địa chỉ email thẳng với phiên bản trên bên cased)

+0

@Syntactic: Lưu ý rằng bộ ký tự mặc định và collation trong MySQL là trường hợp không nhạy cảm theo mặc định. [Nguồn] (http://dev.mysql.com/doc/refman/5.0/en/case-sensitivity.html) –

+0

@Daniel Vassallo Điểm tốt. Học điều gì đó mới mỗi ngày. – Syntactic

+0

Ồ, tôi nghĩ tôi hiểu ý bạn là gì. Nhưng thay vì tìm kiếm thư UPPER, nó trả về tất cả các thư thấp hơn .. khoảng 50.000 người trong số họ :)) Đủ công bằng với trường hợp không nhạy cảm, không có vấn đề gì với việc gửi thư hay bất cứ thứ gì khác, chỉ là nó làm phiền mắt tôi. – w00t

1

Đối với câu hỏi thứ nhất, tôi sẽ chọn một cái gì đó như

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

Chỉ vì mục đích kỹ lưỡng, đây là an toàn nhiều byte mặc dù tôi đã sử dụng LENGTH. Tất cả những gì cần thiết là cho đối số thứ ba của INSERT ít nhất là lớn nhất là phần cuối của chuỗi con.

Câu trả lời của cú pháp về việc tìm kiếm email toàn là một câu trả lời hay. Có thể thực hiện nhanh hơn một chút, mặc dù bạn có thể không nhận thấy sự khác biệt, là

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

Cập nhật: BINARY(email) cần thiết để bắt buộc đối sánh phân biệt chữ hoa chữ thường.

+1

Tôi nghĩ bạn cần bọc '@' trong dấu nháy đơn trong hàm 'INSTR()', nếu không nó sẽ trả về 'NULL'. Ngoài ra tôi đoán truy vấn cuối cùng của bạn sẽ trông giống như 'FROM users WHERE email NOT REGEXP ...'. –

+1

Thật vậy, các dấu nháy đơn cần thiết '@' vì nó trả về 'NULL'. Nó hoạt động sau đó. Truy vấn thứ hai chỉ phù hợp với các email được tạo thành từ các số hoặc + --_ nhưng không có các chữ cái theo thứ tự chữ cái. – w00t

+0

Cảm ơn bạn đã sửa chữa! –

0
UPDATE contacts SET email = REPLACE(email, SUBSTRING_INDEX(email, '@', -1), 'domain.com') 
Các vấn đề liên quan