我有一个MySQL表,其中一列中的所有数据都是以大写形式输入的,但是我需要转换为标题大小写,并且识别出类似于Daring Fireball Title Case脚本的"小词" .
我找到了将字符串转换为小写的优秀解决方案,但标题大小写功能似乎已被排除在我的MySQL版本之外.有一种优雅的方式来做到这一点?
编辑
找到了!从字面上看我的第一个SQL函数.不提供保修.使用前备份数据.:)
首先,定义以下函数:
DROP FUNCTION IF EXISTS lowerword; SET GLOBAL log_bin_trust_function_creators=TRUE; DELIMITER | CREATE FUNCTION lowerword( str VARCHAR(128), word VARCHAR(5) ) RETURNS VARCHAR(128) DETERMINISTIC BEGIN DECLARE i INT DEFAULT 1; DECLARE loc INT; SET loc = LOCATE(CONCAT(word,' '), str, 2); IF loc > 1 THEN WHILE i <= LENGTH (str) AND loc <> 0 DO SET str = INSERT(str,loc,LENGTH(word),LCASE(word)); SET i = loc+LENGTH(word); SET loc = LOCATE(CONCAT(word,' '), str, i); END WHILE; END IF; RETURN str; END; | DELIMITER ;
这将降低str中所有出现的单词.
然后定义此修改后的正确函数:
DROP FUNCTION IF EXISTS tcase; SET GLOBAL log_bin_trust_function_creators=TRUE; DELIMITER | CREATE FUNCTION tcase( str VARCHAR(128) ) RETURNS VARCHAR(128) DETERMINISTIC BEGIN DECLARE c CHAR(1); DECLARE s VARCHAR(128); DECLARE i INT DEFAULT 1; DECLARE bool INT DEFAULT 1; DECLARE punct CHAR(17) DEFAULT ' ()[]{},.-_!@;:?/'; SET s = LCASE( str ); WHILE i <= LENGTH( str ) DO BEGIN SET c = SUBSTRING( s, i, 1 ); IF LOCATE( c, punct ) > 0 THEN SET bool = 1; ELSEIF bool=1 THEN BEGIN IF c >= 'a' AND c <= 'z' THEN BEGIN SET s = CONCAT(LEFT(s,i-1),UCASE(c),SUBSTRING(s,i+1)); SET bool = 0; END; ELSEIF c >= '0' AND c <= '9' THEN SET bool = 0; END IF; END; END IF; SET i = i+1; END; END WHILE; SET s = lowerword(s, 'A'); SET s = lowerword(s, 'An'); SET s = lowerword(s, 'And'); SET s = lowerword(s, 'As'); SET s = lowerword(s, 'At'); SET s = lowerword(s, 'But'); SET s = lowerword(s, 'By'); SET s = lowerword(s, 'For'); SET s = lowerword(s, 'If'); SET s = lowerword(s, 'In'); SET s = lowerword(s, 'Of'); SET s = lowerword(s, 'On'); SET s = lowerword(s, 'Or'); SET s = lowerword(s, 'The'); SET s = lowerword(s, 'To'); SET s = lowerword(s, 'Via'); RETURN s; END; | DELIMITER ;
用法
验证它是否按预期工作:
SELECT tcase(title) FROM table;
用它:
UPDATE table SET title = tcase(title);
资料来源:http://www.artfulsoftware.com/infotree/queries.php?& bw = 1070#122
嗯这样的事可能有用
UPDATE table_name SET `col_name`= CONCAT( UPPER( SUBSTRING( `col_name`, 1, 1 ) ) , LOWER( SUBSTRING( `col_name` FROM 2 ) ) );
如果你需要将自定义首字母缩略词和其他自定义大写模式放入混合中,我已经推广了hobodave的答案:
DELIMITER | CREATE FUNCTION replaceword( str VARCHAR(128), word VARCHAR(128) ) RETURNS VARCHAR(128) DETERMINISTIC BEGIN DECLARE loc INT; DECLARE punct CHAR(27) DEFAULT ' ()[]{},.-_!@;:?/''"#$%^&*<>'; DECLARE lowerWord VARCHAR(128); DECLARE lowerStr VARCHAR(128); IF LENGTH(word) = 0 THEN RETURN str; END IF; SET lowerWord = LOWER(word); SET lowerStr = LOWER(str); SET loc = LOCATE(lowerWord, lowerStr, 1); WHILE loc > 0 DO IF loc = 1 OR LOCATE(SUBSTRING(str, loc-1, 1), punct) > 0 THEN IF loc+LENGTH(word) > LENGTH(str) OR LOCATE(SUBSTRING(str, loc+LENGTH(word), 1), punct) > 0 THEN SET str = INSERT(str,loc,LENGTH(word),word); END IF; END IF; SET loc = LOCATE(lowerWord, lowerStr, loc+LENGTH(word)); END WHILE; RETURN str; END; | DELIMITER ; DELIMITER | CREATE FUNCTION tcase( str VARCHAR(128) ) RETURNS VARCHAR(128) DETERMINISTIC BEGIN DECLARE c CHAR(1); DECLARE s VARCHAR(128); DECLARE i INT DEFAULT 1; DECLARE bool INT DEFAULT 1; DECLARE punct CHAR(27) DEFAULT ' ()[]{},.-_!@;:?/''"#$%^&*<>'; SET s = LCASE( str ); WHILE i <= LENGTH( str ) DO BEGIN SET c = SUBSTRING( s, i, 1 ); IF LOCATE( c, punct ) > 0 THEN SET bool = 1; ELSEIF bool=1 THEN BEGIN IF c >= 'a' AND c <= 'z' THEN BEGIN SET s = CONCAT(LEFT(s,i-1),UCASE(c),SUBSTRING(s,i+1)); SET bool = 0; END; ELSEIF c >= '0' AND c <= '9' THEN SET bool = 0; END IF; END; END IF; SET i = i+1; END; END WHILE; SET s = replaceword(s, 'a'); SET s = replaceword(s, 'an'); SET s = replaceword(s, 'and'); SET s = replaceword(s, 'as'); SET s = replaceword(s, 'at'); SET s = replaceword(s, 'but'); SET s = replaceword(s, 'by'); SET s = replaceword(s, 'for'); SET s = replaceword(s, 'if'); SET s = replaceword(s, 'in'); SET s = replaceword(s, 'n'); SET s = replaceword(s, 'of'); SET s = replaceword(s, 'on'); SET s = replaceword(s, 'or'); SET s = replaceword(s, 'the'); SET s = replaceword(s, 'to'); SET s = replaceword(s, 'via'); SET s = replaceword(s, 'RSS'); SET s = replaceword(s, 'URL'); SET s = replaceword(s, 'PHP'); SET s = replaceword(s, 'SQL'); SET s = replaceword(s, 'OPML'); SET s = replaceword(s, 'DHTML'); SET s = replaceword(s, 'CSV'); SET s = replaceword(s, 'iCal'); SET s = replaceword(s, 'XML'); SET s = replaceword(s, 'PDF'); SET c = SUBSTRING( s, 1, 1 ); IF c >= 'a' AND c <= 'z' THEN SET s = CONCAT(UCASE(c),SUBSTRING(s,2)); END IF; RETURN s; END; | DELIMITER ;
本质上,它由一个不区分大小写的单词替换函数和一个大写每个单词的第一个字母并对特定单词执行某些变换的函数组成.
希望它对某人有帮助.