Giải pháp kích hoạt TRƯỚC KHI CẬP NHẬT:
Bạn có thể tạo một chuỗi chữ hoa gồm chữ và số ngẫu nhiên gồm 6 ký tự bằng:
lpad(conv(floor(rand()*pow(36,6)), 10, 36), 6, 0);
Để không tạo một chuỗi đã tồn tại, bạn có thể sử dụng BEFORE UPDATE
cò súng.
DELIMITER //
CREATE TRIGGER `unique_codes_before_update`
BEFORE UPDATE ON `unique_codes` FOR EACH ROW
BEGIN
declare ready int default 0;
declare rnd_str text;
if new.CODE is null then
while not ready do
set rnd_str := lpad(conv(floor(rand()*pow(36,6)), 10, 36), 6, 0);
if not exists (select * from unique_codes where CODE = rnd_str) then
set new.CODE = rnd_str;
set ready := 1;
end if;
end while;
end if;
END//
DELIMITER ;
Mỗi khi bạn đặt CODE
của mình cột thành NULL
trong một UPDATE
, trình kích hoạt sẽ tạo một chuỗi ngẫu nhiên mới trong một vòng lặp cho đến khi không tìm thấy kết quả phù hợp nào trong bảng.
Bây giờ bạn có thể thay thế tất cả các giá trị NULL bằng:
update unique_codes set CODE = NULL where code is NULL;
Trong demo SQLFiddle tại đây tôi sử dụng một chuỗi ngẫu nhiên một ký tự để chứng minh rằng không có giá trị nào bị trùng lặp.
Bạn cũng có thể sử dụng mã tương tự trong một BEFORE INSERT
cò súng. Bằng cách này, bạn chỉ có thể chèn các hàng mới với CODE=NULL
và trình kích hoạt sẽ đặt nó thành một chuỗi ngẫu nhiên duy nhất mới. Và bạn sẽ không bao giờ cần cập nhật lại.
Câu trả lời ban đầu (32 chuỗi ký tự):
select lpad(conv(floor(rand()*pow(36,8)), 10, 36), 8, 0) as rnd_str_8;
-- output example: 3AHX44TF
sẽ tạo ra một chuỗi ngẫu nhiên gồm 8 ký tự chữ và số viết hoa. Ghép bốn trong số chúng để có 32 ký tự:
select concat(
lpad(conv(floor(rand()*pow(36,8)), 10, 36), 8, 0),
lpad(conv(floor(rand()*pow(36,8)), 10, 36), 8, 0),
lpad(conv(floor(rand()*pow(36,8)), 10, 36), 8, 0),
lpad(conv(floor(rand()*pow(36,8)), 10, 36), 8, 0)
) as rnd_str_32;
-- output example: KGC8A8EGKE7E4MGD4M09U9YWXVF6VDDS
http://sqlfiddle.com/#!9/9eecb7d/76933
Vậy còn uniqness thì sao? Chà - cố gắng tạo các bản sao;-)