mysql-如何更新“address@domain.com”中的“domain.com”

Posted

技术标签:

【中文标题】mysql-如何更新“address@domain.com”中的“domain.com”【英文标题】:Mysql-how to update the "domain.com" in "address@domain.com" 【发布时间】:2011-02-24 05:24:59 【问题描述】:

在我的数据库中,我有很多用户拼错了他们的电子邮件地址。这反过来又导致我的 postfix 在发送时事通讯时退回很多邮件。 形式包括(但不限于)“yaho.com”、“yahho.com”等 很烦人!

所以我一直在尝试将这些记录更新为正确的值。 执行select email from users where email like '%@yaho%' and email not like '%yahoo%'; 并获取列表后,我被卡住了,因为我不知道如何只更新yaho 部分。我需要保留用户名。

所以我以为我只是转储数据库并使用vim替换,但我无法逃脱@符号..

顺便说一句,我如何选择所有用大写字母书写的电子邮件地址? select upper(email) from users; 只会将所有内容转换为大写字母,而我只需要找出已经写成大写字母的邮件。

【问题讨论】:

如果您需要有效的电子邮件地址,您可以在注册时添加电子邮件验证吗?您不能保证将 bob@yaho.com 更改为 bob@yahoo.com 会真正到达您的注册用户,也不能保证它也不会产生反弹。 确实你是对的,我还认为任何理智的人都应该添加验证。但我只是这里的系统管理员,我想从我这边解决这种情况。将不得不提交一个错误或smth。 【参考方案1】:

您可能想尝试以下方法:

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

测试用例:

CREATE TABLE users (email varchar(50));

INSERT INTO users VALUES ('test1@yahoo.com');
INSERT INTO users VALUES ('test2@yaho.com');
INSERT INTO users VALUES ('test3@yahoo.com');


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           |
+-----------------+
| test1@yahoo.com |
| test2@yahoo.com |
| test3@yahoo.com |
+-----------------+
3 rows in set (0.00 sec)

要回答您的第二个问题,您可能需要use a case sensitive collation,例如latin1_general_cs

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

测试用例:

INSERT INTO users VALUES ('TEST4@YAHOO.COM');


SELECT * FROM users;   
+-----------------+
| email           |
+-----------------+
| test1@yahoo.com |
| test2@yahoo.com |
| test3@yahoo.com |
| TEST4@YAHOO.COM |
+-----------------+
4 rows in set (0.00 sec)


SELECT * FROM users WHERE email COLLATE latin1_general_cs = UPPER(email);
+-----------------+
| email           |
+-----------------+
| TEST4@YAHOO.COM |
+-----------------+
1 row in set (0.00 sec)

【讨论】:

很好的例子!工作没有问题。不过有一件事,数据库是 UTF8,所以我不能使用 latin1 排序规则。但没什么大不了的,SELECT 并不重要,我只是将所有内容更新为小写。谢谢! 多年后我仍然会回到这个答案。 我正在尝试将 @ 放入 varchar 中。但是说extranoues...如何在mysql中输入电子邮件地址?【参考方案2】:

要解决您的第二个问题(关于查找以大写字母书写的电子邮件),以下内容可能会有所帮助:

select email from users where upper(email) = email

(如果语法不完全正确,请原谅我,因为我已经习惯了 DB2。我们的想法是将直接电子邮件地址与大写版本进行比较。)

【讨论】:

@Syntactic:注意 MySQL 中的默认字符集和排序规则默认不区分大小写。 Source @Daniel Vassallo 好点。每天学习新东西。 哦,我想我明白你的意思了。但是它没有找到大写的邮件,而是返回所有小写的邮件.. 大约 50.000 个 :)) 不区分大小写,发送邮件或其他任何东西都没有问题,只是它打扰了我的眼睛。跨度> @w00t:如果你想把所有的邮件都转成小写,你可以这样做:UPDATE users SET email = lower(email); @w00t:在应用端做,在插入/更新数据的时候,你就不用再担心了。【参考方案3】:
UPDATE users SET email = REPLACE( email, SUBSTRING_INDEX( email,  '@', -1 ) ,  CONCAT(user_id, 'domain.com' ) ) WHERE [MYSQL CONDITION];

将实时电子邮件地址更新为测试电子邮件地址

【讨论】:

【参考方案4】:

您可以尝试将INSTRSUBSTRLEFT 一起使用以获取“@”符号之前的部分。

SELECT LEFT("foo@yaho.com",INSTR("foo@yaho.com","@")-1); 之类的东西似乎有效。

【讨论】:

【参考方案5】:

对于第一个问题,我会选择类似

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

只是为了彻底,即使我使用了LENGTH,这也是多字节安全的。所需要的只是INSERT 的第三个参数至少与子字符串的结尾一样大。

Syntactic 找到全大写电子邮件的答案是一个很好的答案。可能性能稍快一些,尽管您可能不会注意到差异,是

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

更新:需要BINARY(email) 来强制区分大小写匹配。

【讨论】:

我认为您需要在INSTR() 函数中将@ 用单引号括起来,否则它将返回NULL。另外我猜你的最后一个查询应该类似于FROM users WHERE email NOT REGEXP ... 确实,@ 需要单引号,因为它返回了NULL。之后奏效了。第二个查询仅匹配由数字或 +--_ 组成的电子邮件,但不匹配字母。【参考方案6】:
UPDATE contacts SET email = REPLACE(email, SUBSTRING_INDEX(email, '@', -1), 'domain.com')

【讨论】:

以上是关于mysql-如何更新“address@domain.com”中的“domain.com”的主要内容,如果未能解决你的问题,请参考以下文章

邮件 PHP 是如何工作的?

带有 dnsmasq 的通配符子域

KnockoutJS 映射插件 (observableArray)

xampp php 发送邮件

mysql 如何更新数组中的值

mysql 如何只更新其中一条数据?