我有一个mysql数据库,其中所有的id(主键)都是ulid。问题在于它存储为 VARCHAR(255)。我想通过以下方式纠正它(更改为二进制):
问题是将 utf8mb3 字符集中存储为 VARCHAR(255) 的 ulid 转换为二进制。我尝试过以下功能:
DELIMITER //
-- The input is of type CHAR(26) for simplicity as converting varchar(255) to char(26) does not seem to be a problem, the problem is converting it further to binary
CREATE FUNCTION ConvertULIDToBinary(ulid CHAR(26) CHARACTER SET utf8mb3)
RETURNS BINARY(16)
DETERMINISTIC
BEGIN
DECLARE result BINARY(16);
SET result = UNHEX(CONCAT(
LPAD(CONV(SUBSTRING(ulid, 1, 6), 36, 16), 10, '0'),
LPAD(CONV(SUBSTRING(ulid, 7, 6), 36, 16), 10, '0'),
LPAD(CONV(SUBSTRING(ulid, 13, 6), 36, 16), 10, '0'),
LPAD(CONV(SUBSTRING(ulid, 19, 8), 36, 16), 16, '0')
));
RETURN result;
END //
DELIMITER ;
但是如果我运行它,我会收到以下错误:
SQL Error (1406) in statement #3: Data too long for column 'result' at row 1
尝试以下功能:
delimiter //
DROP FUNCTION IF EXISTS ULID_DECODE//
CREATE FUNCTION ULID_DECODE (s CHAR(26)) RETURNS BINARY(16) DETERMINISTIC
BEGIN
DECLARE s_base32 CHAR(26);
SET s_base32 = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(UPPER(s), 'J', 'I'), 'K', 'J'), 'M', 'K'), 'N', 'L'), 'P', 'M'), 'Q', 'N'), 'R', 'O'), 'S', 'P'), 'T', 'Q'), 'V', 'R'), 'W', 'S'), 'X', 'T'), 'Y', 'U'), 'Z', 'V');
RETURN UNHEX(CONCAT(LPAD(CONV(SUBSTRING(s_base32, 1, 2), 32, 16), 2, '0'), LPAD(CONV(SUBSTRING(s_base32, 3, 12), 32, 16), 15, '0'), LPAD(CONV(SUBSTRING(s_base32, 15, 12), 32, 16), 15, '0')));
END//
delimiter ;