Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> MySQL

Triển khai ngược lại INITCAP() trong MySQL: Chữ thường đầu từ, còn lại HOA

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

  1. Chuyển toàn bộ chuỗi thành HOA (UPPER).
  2. 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).
  3. 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.