我可以使用MySQL的TRIM()
方法来清理包含前导或尾随空格的字段,使用UPDATE
操作,如下所示:
UPDATE Foo SET field = TRIM(field);
在运行这个之前,我希望能够实际看到这会影响哪些字段。我尝试了这个方法,但是返回了 0 个结果:
SELECT * FROM Foo WHERE field != TRIM(field);
看起来这应该可以工作,但实际上并没有。
有人有解决方案吗?另外,很好奇为什么这不能工作...
PADSPACE
类型。这意味着,在MySQL中,所有的CHAR
和VARCHAR
值都不考虑任何尾随空格进行比较。SELECT * FROM Foo WHERE CHAR_LENGTH(field) != CHAR_LENGTH(TRIM(field))
SELECT *
FROM
`foo`
WHERE
(name LIKE ' %')
OR
(name LIKE '% ')
LIKE
会尊重前导和尾随空格,而=
则不会:https://bugs.mysql.com/bug.php?id=64772 - Joshua Pinter另一种解决方案可能是使用 SUBSTRING()
和 IN
来将字符串的最后一个字符和第一个字符与空格字符列表进行比较...
(SUBSTRING(@s, 1, 1) IN (' ', '\t', '\n', '\r') OR SUBSTRING(@s, -1, 1) IN (' ', '\t', '\n', '\r'))
...其中@s
是任何输入字符串。根据您的情况,可以添加额外的空格字符到比较列表中。
以下是一个简单的测试,演示该表达式如何处理各种字符串输入:
SET @s_normal = 'x';
SET @s_ws_leading = '\tx';
SET @s_ws_trailing = 'x ';
SET @s_ws_both = '\rx ';
SELECT
NOT(SUBSTRING(@s_normal, 1, 1) IN (' ', '\t', '\n', '\r') OR SUBSTRING(@s_normal, -1, 1) IN (' ', '\t', '\n', '\r')) test_normal #=> 1 (PASS)
, (SUBSTRING(@s_ws_leading, 1, 1) IN (' ', '\t', '\n', '\r') OR SUBSTRING(@s_ws_leading, -1, 1) IN (' ', '\t', '\n', '\r')) test_ws_leading #=> 1 (PASS)
, (SUBSTRING(@s_ws_trailing, 1, 1) IN (' ', '\t', '\n', '\r') OR SUBSTRING(@s_ws_trailing,-1, 1) IN (' ', '\t', '\n', '\r')) test_ws_trailing #=> 1 (PASS)
, (SUBSTRING(@s_ws_both, 1, 1) IN (' ', '\t', '\n', '\r') OR SUBSTRING(@s_ws_both, -1, 1) IN (' ', '\t', '\n', '\r')) test_ws_both #=> 1 (PASS)
;
如果这是您经常要做的事情,您也可以为此创建一个函数:
DROP FUNCTION IF EXISTS has_leading_or_trailing_whitespace;
CREATE FUNCTION has_leading_or_trailing_whitespace(s VARCHAR(2000))
RETURNS BOOLEAN
DETERMINISTIC
RETURN (SUBSTRING(s, 1, 1) IN (' ', '\t', '\n', '\r') OR SUBSTRING(s, -1, 1) IN (' ', '\t', '\n', '\r'))
;
# test
SELECT
NOT(has_leading_or_trailing_whitespace(@s_normal )) #=> 1 (PASS)
, has_leading_or_trailing_whitespace(@s_ws_leading ) #=> 1 (PASS)
, has_leading_or_trailing_whitespace(@s_ws_trailing) #=> 1 (PASS)
, has_leading_or_trailing_whitespace(@s_ws_both ) #=> 1 (PASS)
;
!=
和<>
似乎没有区别。 - Michael