Vấn đề
MySQL không có hàm ngược của INITCAP() (viết hoa chữ cái đầu từ). Cần tự tạo function để: chữ cái đầu từ → thường, các chữ còn lại → HOA.
Tạo Function
DELIMITER //
CREATE FUNCTION convertFirstLetterToLowerAndRemainingToCapital(value VARCHAR(250))
RETURNS VARCHAR(250)
DETERMINISTIC
BEGIN
DECLARE valueLength INT;
DECLARE l INT;
SET valueLength = CHAR_LENGTH(value);
SET value = UPPER(value);
SET l = 0;
WHILE (l < valueLength) DO
IF (MID(value, l, 1) = ' ' OR l = 0) THEN
IF (l < valueLength) THEN
SET value = CONCAT(
LEFT(value, l),
LOWER(MID(value, l + 1, 1)),
RIGHT(value, valueLength - l - 1)
);
END IF;
END IF;
SET l = l + 1;
END WHILE;
RETURN value;
END //
DELIMITER ;
Test function
SELECT convertFirstLetterToLowerAndRemainingToCapital('Introduction To MySQL');
Kết quả:
+-------------------------------------------------------------------------+
| convertFirstLetterToLowerAndRemainingToCapital('Introduction To MySQL') |
+-------------------------------------------------------------------------+
| iNTRODUCTION tO mYSQL |
+-------------------------------------------------------------------------+
Giải thích thuật toán
- Chuyển toàn bộ chuỗi thành HOA (
UPPER). - Duyệt từng ký tự, nếu là đầu chuỗi (l=0) hoặc ký tự trước là khoảng trắng → chuyển ký tự hiện tại thành THƯỜNG (
LOWER). - Ghép lại chuỗi bằng
CONCAT(LEFT, LOWER(mid), RIGHT).
Cách tiếp cận hiện đại (MySQL 8.0+)
Dùng REGEXP_REPLACE (cần MySQL 8.0.4+):
SELECT REGEXP_REPLACE(UPPER('Introduction To MySQL'), '(^| )([A-Z])', '\\1\\2');
-- Cần điều chỉnh regex để lower case group 2, hiện MySQL REGEXP_REPLACE không hỗ trợ callback function.
Thay thế thực tế trong MySQL 8.0:
SELECT LOWER(SUBSTRING(UPPER(str), 1, 1)) || SUBSTRING(UPPER(str), 2) -- chỉ từ đầu tiên
-- Cho nhiều từ: cần stored function hoặc recursive CTE
Lưu ý
- Function trên là
DETERMINISTIC→ có thể cache kết quả. - Xử lý Unicode: cần collation hỗ trợ (utf8mb4).
- Hiệu năng: loop từng ký tự chậm trên chuỗi dài, dữ liệu lớn.