J'utilise MySql 5.5.37. J'ai un tableau avec les colonnes suivantes
+------------------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------------+------------------+------+-----+---------+-------+
| ID | varchar(32) | NO | PRI | NULL | |
| CODE | varchar(6) | NO | UNI | NULL | |
La colonne de code est unique et ma colonne ID est un GUID. J'aimerais mettre à jour un certain nombre de lignes, en fonction de certains critères du tableau ci-dessus (par exemple, WHERE COLUMN1 = 0). Comment générer des codes aléatoires et uniques à 6 caractères (idéalement des lettres et des chiffres) pour ma colonne CODE, de manière à ne pas violer la contrainte unique de mon tableau? Notez que les colonnes de la table qui ne répondent pas aux critères (par exemple, où COLUMN1 <> 0) ont déjà des valeurs uniques pour la colonne CODE.
Modifier: C’est différent de cette question - Génération d’une chaîne aléatoire et unique de 8 caractères avec MySQL car ce lien traite des ID qui sont numériques. Mes identifiants sont des chaînes de 32 caractères. De plus, leur solution ne tient pas compte du fait qu'il peut y avoir des valeurs dans la table avant d'exécuter les instructions que je veux exécuter qui vont générer des valeurs uniques pour la colonne en question.
BEFORE UPDATE solution de déclenchement:
Vous pouvez créer une chaîne alphanumérique alphanumérique aléatoire de 6 caractères avec:
lpad(conv(floor(Rand()*pow(36,6)), 10, 36), 6, 0);
Pour ne pas créer une chaîne existante, vous pouvez utiliser un déclencheur BEFORE UPDATE
.
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 ;
Chaque fois que vous définissez votre colonne CODE
sur NULL
dans une instruction UPDATE
, le déclencheur créera une nouvelle chaîne aléatoire dans une boucle jusqu'à ce qu'aucune correspondance ne soit trouvée dans la table.
Vous pouvez maintenant remplacer toutes les valeurs NULL par:
update unique_codes set CODE = NULL where code is NULL;
Dans la démonstration de SQLFiddle, ici i utilise une chaîne aléatoire d’un caractère pour démontrer qu’aucune valeur n’est dupliquée.
Vous pouvez également utiliser le même code dans un déclencheur BEFORE INSERT
. De cette façon, vous pouvez simplement insérer de nouvelles lignes avec CODE=NULL
et le déclencheur le définira comme nouvelle chaîne aléatoire unique. Et vous n'aurez plus jamais besoin de le mettre à jour.
Réponse originale (chaînes de 32 caractères):
select lpad(conv(floor(Rand()*pow(36,8)), 10, 36), 8, 0) as rnd_str_8;
-- output example: 3AHX44TF
générera une chaîne aléatoire alphanumérique de 8 caractères. Concaténer quatre d'entre eux pour obtenir 32 caractères:
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
Alors, qu'en est-il de l'uniqness? Eh bien - essayez de générer des doublons ;-)
CONV(CONV(( SELECT MAX(CODE) FROM tbl ), 36, 10) + 1, 10, 36)
vous obtiendrez le prochain «numéro» encodé en base 36 (chiffres et lettres majuscules).
Par exemple:
SELECT CONV(CONV(( 'A1B2C' ), 36, 10) + 1, 10, 36); --> 'A1B2D'
DELIMITER $$
USE `db` $$
DROP PROCEDURE IF EXISTS `GenerateUniqueValue`$$
CREATE PROCEDURE `GenerateUniqueValue`(IN tableName VARCHAR(255),IN columnName VARCHAR(255))
BEGIN
DECLARE uniqueValue VARCHAR(8) DEFAULT "";
WHILE LENGTH(uniqueValue) = 0 DO
SELECT CONCAT(SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789', Rand()*34+1, 1),
SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789', Rand()*34+1, 1),
SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789', Rand()*34+1, 1),
SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789', Rand()*34+1, 1),
SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789', Rand()*34+1, 1),
SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789', Rand()*34+1, 1),
SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789', Rand()*34+1, 1),
SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789', Rand()*34+1, 1)
) INTO @newUniqueValue;
SET @rcount = -1;
SET @query=CONCAT('SELECT COUNT(*) INTO @rcount FROM ',tableName,' WHERE ',columnName,' like ''',@newUniqueValue,'''');
PREPARE stmt FROM @query;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
IF @rcount = 0 THEN
SET uniqueValue = @newUniqueValue ;
END IF ;
END WHILE ;
SELECT uniqueValue;
END$$
DELIMITER ;
Appelez cette procédure stockée comme
Call GenerateUniqueValue('tableName','columnName')
Cela vous donnera une chaîne unique de 8 caractères à chaque fois.
Essayez ceci pour le code
SELECT LEFT(MD5(NOW()), 6) AS CODE;
LEFT(MD5(NOW()), 6)
ceci retournera un code unique avec 6 caractères.
Essayez d'une autre manière comme ça
SELECT LEFT(UUID(), 6);
LEFT(UUID(), 6)
Ceci retournera également un code unique