Menghasilkan string 8 karakter acak & unik menggunakan MySQL

110

Saya sedang mengerjakan game yang melibatkan kendaraan di beberapa titik. Saya memiliki tabel MySQL bernama "kendaraan" yang berisi data tentang kendaraan, termasuk kolom "pelat" yang menyimpan Plat untuk kendaraan tersebut.

Sekarang inilah bagian yang bermasalah dengan saya. Saya perlu menemukan pelat nomor yang tidak digunakan sebelum membuat kendaraan baru - itu harus berupa string acak 8 karakter alfanumerik. Bagaimana saya mencapai ini adalah menggunakan while loop di Lua, yang merupakan bahasa pemrograman saya, untuk menghasilkan string dan query DB untuk melihat apakah itu digunakan. Namun, seiring bertambahnya jumlah kendaraan, saya perkirakan ini akan menjadi semakin tidak efisien seperti sekarang. Oleh karena itu, saya memutuskan untuk mencoba dan memecahkan masalah ini menggunakan kueri MySQL.

Kueri yang saya butuhkan seharusnya hanya menghasilkan string alfanumerik 8 karakter yang belum ada dalam tabel. Saya memikirkan pendekatan generate & check loop lagi, tetapi saya tidak membatasi pertanyaan ini hanya untuk berjaga-jaga jika ada pertanyaan yang lebih efisien. Saya telah dapat menghasilkan string dengan mendefinisikan string yang berisi semua karakter yang diizinkan dan secara acak melakukan substring, dan tidak lebih.

Bantuan apa pun dihargai.

funstein
sumber
Seberapa acak Anda membutuhkan ini? Jika seseorang menerima plat nomor tertentu, apakah penting atau tidak apakah mereka dapat menentukan plat nomor berikutnya atau sebelumnya yang Anda berikan?
Damien_The_Unbeliever
@YaK Lihat jawaban saya tentang bagaimana menghindari kemungkinan tabrakan yang kecil sekalipun
Eugen Rieck

Jawaban:

87

Masalah ini terdiri dari dua sub-masalah yang sangat berbeda:

  • stringnya pasti terlihat acak
  • string harus unik

Meskipun keacakan cukup mudah dicapai, keunikan tanpa retry loop tidak. Ini membawa kita untuk berkonsentrasi pada keunikan terlebih dahulu. Keunikan non-acak bisa dengan mudah dicapai dengan AUTO_INCREMENT. Jadi menggunakan transformasi pseudo-random yang menjaga keunikan akan baik-baik saja:

  • Hash disarankan oleh @paul
  • AES-encrypt juga cocok
  • Tapi ada yang bagus: RAND(N)sendiri!

Urutan nomor acak yang dibuat oleh benih yang sama dijamin akan ada

  • direproduksi
  • berbeda untuk 8 iterasi pertama
  • jika benihnya adalah an INT32

Jadi kami menggunakan pendekatan @ AndreyVolk atau @ GordonLinoff, tetapi dengan seeded RAND :

misalnya Assumin idadalah AUTO_INCREMENTkolom:

INSERT INTO vehicles VALUES (blah); -- leaving out the number plate
SELECT @lid:=LAST_INSERT_ID();
UPDATE vehicles SET numberplate=concat(
  substring('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand(@seed:=round(rand(@lid)*4294967296))*36+1, 1),
  substring('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand(@seed:=round(rand(@seed)*4294967296))*36+1, 1),
  substring('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand(@seed:=round(rand(@seed)*4294967296))*36+1, 1),
  substring('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand(@seed:=round(rand(@seed)*4294967296))*36+1, 1),
  substring('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand(@seed:=round(rand(@seed)*4294967296))*36+1, 1),
  substring('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand(@seed:=round(rand(@seed)*4294967296))*36+1, 1),
  substring('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand(@seed:=round(rand(@seed)*4294967296))*36+1, 1),
  substring('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand(@seed)*36+1, 1)
)
WHERE id=@lid;
Eugen Rieck
sumber
Pendekatan yang sangat menarik, tetapi Anda mungkin bermaksud RAND(LAST_INSERT_ID()); UPDATE vehicles (...) , rand()*36+1, (...)(atau mengembalikan 8 kali karakter yang sama). Bagaimana kita bisa yakin bahwa 8 panggilan berurutan ke rand()dijamin mengembalikan urutan yang berbeda jika dijalankan dengan seed yang berbeda?
RandomSeed
8
Saya hanya ingin tahu. Mengapa Anda menggunakan angka-angka itu ..4294967296)) * 36 + 1?
Mick
7
Ini agak tua tapi saya ingin mencatat bahwa saya harus menambahkan FLOOR()sekitar parameter substring kedua: substring('ABC … 789', floor(rand(@seed:= … )*36+1), 1), Pada beberapa kesempatan, substring mencoba memilih karakter 36.9, yang bila dibulatkan ke 37, tidak akan menghasilkan karakter yang dipilih.
Phillip Dodson
4
Anda tidak dapat memanggil string acak jika dapat direproduksi. Dan duplikat juga dimungkinkan, karena Anda sedang menggunakan floor(). Sqlfiddle ini menunjukkan, bahwa duplikat dibuat untuk string sepanjang tiga karakter.
Paul Spiegel
6
@EugenRieck Saya tidak mengerti bagaimana Anda mendapatkan nomor Anda ("2 ^ 32 iterasi pertama"). Tetapi saya hanya perlu satu contoh duplikat untuk menyangkal konsep ini. Untuk ID 193844dan 775771algoritma Anda akan menghasilkan string yang sama T82X711( demo ).
Paul Spiegel
113

Seperti yang saya nyatakan dalam komentar saya, saya tidak akan peduli dengan kemungkinan tabrakan. Buat saja string acak dan periksa apakah ada. Jika ya, coba lagi dan Anda tidak perlu melakukannya lebih dari beberapa kali kecuali Anda telah menetapkan sejumlah besar piring.

Solusi lain untuk menghasilkan string pseudo-random sepanjang 8 karakter dalam SQL murni (Saya):

SELECT LEFT(UUID(), 8);

Anda dapat mencoba yang berikut (pseudo-code):

DO 
    SELECT LEFT(UUID(), 8) INTO @plate;
    INSERT INTO plates (@plate);
WHILE there_is_a_unique_constraint_violation
-- @plate is your newly assigned plate number

Karena posting ini telah menerima tingkat perhatian yang tidak terduga, izinkan saya menyoroti komentar ADTC : potongan kode di atas cukup bodoh dan menghasilkan digit berurutan.

Untuk keacakan yang tidak terlalu bodoh, cobalah sesuatu seperti ini:

SELECT LEFT(MD5(RAND()), 8)

Dan untuk keacakan yang benar (aman secara kriptograpik), gunakan RANDOM_BYTES()daripada RAND()(tetapi kemudian saya akan mempertimbangkan untuk memindahkan logika ini ke lapisan aplikasi).

RandomSeed
sumber
Terima kasih atas solusi Anda, saya punya satu pertanyaan tentang UUID. Berapa banyak kemungkinan id yang Anda hasilkan 8 karakter terulang lagi.
TR-Ahmed
1
@ user3099183 Secara resmi , "sangat rendah". 16 ^ 8 adalah sekitar 4 miliar kemungkinan string.
RandomSeed
23
Harap perhatikan bahwa 8 karakter pertama UUID tidak acak, tetapi berurutan, karena didasarkan pada stempel waktu.
ADTC
Saya ingin menghasilkan string acak panjang 9 karakter, dan ketika saya menggunakan 9kode Anda SELECT LEFT(UUID(), 9);, selalu ada -di akhir string yang dihasilkan sebagai karakter kesembilan. Itu konstan. Mengapa?
Martin AJ
3
@MartinAJ karena stringnya adalah uuid . Anda dapat dengan mudah mengganti tanda hubung misalnyaSELECT LEFT(REPLACE(UUID(), '-', ''), 16);
jchook
53

Bagaimana dengan menghitung hash MD5 (atau lainnya) dari bilangan bulat berurutan, lalu mengambil 8 karakter pertama.

yaitu

MD5(1) = c4ca4238a0b923820dcc509a6f75849b => c4ca4238
MD5(2) = c81e728d9d4c2f636f067f89cc14862c => c81e728d
MD5(3) = eccbc87e4b5ce2fe28308fd9f2a7baf3 => eccbc87e

dll.

peringatan: Saya tidak tahu berapa banyak yang dapat Anda alokasikan sebelum tabrakan (tetapi itu akan menjadi nilai yang diketahui dan konstan).

sunting: Sekarang ini adalah jawaban lama, tetapi saya melihatnya lagi dengan waktu di tangan saya, jadi, dari pengamatan ...

Peluang semua angka = 2,35%

Peluang semua huruf = 0,05%

Tabrakan pertama saat MD5 (82945) = "7b763dcb ..." (hasil yang sama seperti MD5 (25302))

paul
sumber
2
Ide bagus, bisa menggunakannya di kunci utama. Akan mengingat ini untuk proyek masa depan, terima kasih!
funstein
2
Ada kemungkinan ini bisa terjadi hanya dengan angka
Mladen Janjetovic
9
Itu sama sekali tidak acak.
paul
1
Anda bisa membuatnya lebih "acak" jika alih-alih menggunakan auto incremental id, Anda menggunakan datetime di mana penyisipan dilakukan, yang juga unik.
Javier La Banca
35

Buat string acak

Berikut adalah fungsi MySQL untuk membuat string acak dengan panjang tertentu.

DELIMITER $$

CREATE DEFINER=`root`@`%` FUNCTION `RandString`(length SMALLINT(3)) RETURNS varchar(100) CHARSET utf8
begin
    SET @returnStr = '';
    SET @allowedChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    SET @i = 0;

    WHILE (@i < length) DO
        SET @returnStr = CONCAT(@returnStr, substring(@allowedChars, FLOOR(RAND() * LENGTH(@allowedChars) + 1), 1));
        SET @i = @i + 1;
    END WHILE;

    RETURN @returnStr;
END

Pemakaian SELECT RANDSTRING(8) untuk mengembalikan string 8 karakter.

Anda dapat menyesuaikan file @allowedChars .

Keunikan tidak dijamin - seperti yang akan Anda lihat di komentar untuk solusi lain, ini tidak mungkin. Sebagai gantinya Anda harus membuat string, periksa apakah sudah digunakan, dan coba lagi jika sudah digunakan.


Periksa apakah string acak sudah digunakan

Jika kita ingin menyimpan kode pemeriksaan tabrakan dari aplikasi, kita dapat membuat pemicu:

DELIMITER $$

CREATE TRIGGER Vehicle_beforeInsert
  BEFORE INSERT ON `Vehicle`
  FOR EACH ROW
  BEGIN
    SET @vehicleId = 1;
    WHILE (@vehicleId IS NOT NULL) DO 
      SET NEW.plate = RANDSTRING(8);
      SET @vehicleId = (SELECT id FROM `Vehicle` WHERE `plate` = NEW.plate);
    END WHILE;
  END;$$
DELIMITER ;
Paddy Mann
sumber
6
ini harus menjadi jawaban yang diterima, jelas dan langsung ke intinya, bekerja dengan baik untuk saya, terima kasih @ paddy-mann
Saif
Ini adalah solusi terbaik menurut saya. Terima kasih sobat!
Pronoy999
23

Berikut salah satu caranya, menggunakan alfa numerik sebagai karakter yang valid:

select concat(substring('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand()*36+1, 1),
              substring('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand()*36+1, 1),
              substring('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand()*36+1, 1),
              substring('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand()*36+1, 1),
              substring('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand()*36+1, 1),
              substring('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand()*36+1, 1),
              substring('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand()*36+1, 1),
              substring('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand()*36+1, 1)
             ) as LicensePlaceNumber;

Perhatikan bahwa tidak ada jaminan keunikan. Anda harus memeriksanya secara terpisah.

Gordon Linoff
sumber
7
gunakan floor (rand () * 36 + 1) sebagai gantinya. Jika tidak, beberapa hasil akan 'singkat'.
Fraggle
2
seharusnya ada 35 + 1 bukan 36 + 1! Jika tidak, Anda akan mendapatkan beberapa string dengan 8 karakter dan beberapa di antaranya dengan 7
BIOHAZARD
23

Berikut metode lain untuk menghasilkan string acak:

SELECT SUBSTRING(MD5(RAND()) FROM 1 FOR 8) AS myrandomstring

sedang
sumber
16

Anda dapat menggunakan fungsi rand () dan char () MySQL :

select concat( 
    char(round(rand()*25)+97),
    char(round(rand()*25)+97),
    char(round(rand()*25)+97),
    char(round(rand()*25)+97),
    char(round(rand()*25)+97),
    char(round(rand()*25)+97),
    char(round(rand()*25)+97),
    char(round(rand()*25)+97)
) as name;
Andrey Volk
sumber
14

Anda dapat membuat string alfanumerik acak dengan:

lpad(conv(floor(rand()*pow(36,8)), 10, 36), 8, 0);

Anda dapat menggunakannya di BEFORE INSERTpemicu dan memeriksa duplikat di loop sementara:

CREATE TABLE `vehicles` (
    `plate` CHAR(8) NULL DEFAULT NULL,
    `data` VARCHAR(50) NOT NULL,
    UNIQUE INDEX `plate` (`plate`)
);

DELIMITER //
CREATE TRIGGER `vehicles_before_insert` BEFORE INSERT ON `vehicles`
FOR EACH ROW BEGIN

    declare str_len int default 8;
    declare ready int default 0;
    declare rnd_str text;
    while not ready do
        set rnd_str := lpad(conv(floor(rand()*pow(36,str_len)), 10, 36), str_len, 0);
        if not exists (select * from vehicles where plate = rnd_str) then
            set new.plate = rnd_str;
            set ready := 1;
        end if;
    end while;

END//
DELIMITER ;

Sekarang masukkan saja data Anda seperti

insert into vehicles(col1, col2) values ('value1', 'value2');

Dan pemicunya akan menghasilkan nilai untuk platekolom tersebut.

( demo sqlfiddle )

Itu berfungsi seperti ini jika kolom memungkinkan NULLs. Jika Anda menginginkannya NOT NULL Anda perlu menentukan nilai default

`plate` CHAR(8) NOT NULL DEFAULT 'default',

Anda juga dapat menggunakan algoritme penghasil string acak lainnya di pemicu jika huruf besar alfanumerik bukan yang Anda inginkan. Tapi pemicunya akan menjaga keunikan.

Paul Spiegel
sumber
Luar biasa! Inilah yang saya inginkan. Saya hanya ingin memahami bagaimana itu diubah menjadi string. Kenapa ada pow, apa yang harus dilakukan, menambah angka dan sebagainya. Bagaimanapun, terima kasih.
Akxe
@Akxe conv () dapat digunakan untuk mengonversi angka menjadi string alfanumerik. pow(36,8)-1adalah representasi numerik dari ZZZZZZZZ. Jadi kami menghasilkan bilangan bulat acak antara 0dan '36 ^ 8-1 '(dari 0ke 2821109907455) dan mengubahnya menjadi string alfanumerik antara 0dan ZZZZZZZZunsing conv(). lapad () akan mengisi string dengan angka nol hingga memiliki panjang 8.
Paul Spiegel
Anda tuan adalah seorang jenius. Saya membayangkan menambahkan huruf kecil tidak mungkin karena karakter tidak kontinuitas? (91-96) Bukannya aku membutuhkannya, hanya penasaran ...
Akxe
@Akxe conv()hanya mendukung basis hingga 36 (10 digit + 26 huruf besar). Jika Anda ingin memasukkan huruf kecil, Anda memerlukan cara lain untuk mengubah angka menjadi string.
Paul Spiegel
Peringatan: tidak berfungsi untuk str_len> 13. Dari 14, Anda selalu mendapatkan '3W5E11264SGSF'. ;-)
Gerard H. Pille
6

Untuk menghasilkan string acak, Anda dapat menggunakan:

SUBSTRING(MD5(RAND()) FROM 1 FOR 8)

Anda menerima sesuatu seperti itu:

353E50CC

Nikita G.
sumber
5

Untuk String yang terdiri dari 8 angka acak dan huruf besar dan kecil, inilah solusi saya:

LPAD(LEFT(REPLACE(REPLACE(REPLACE(TO_BASE64(UNHEX(MD5(RAND()))), "/", ""), "+", ""), "=", ""), 8), 8, 0)

Dijelaskan dari dalam ke luar:

  1. RAND menghasilkan angka acak antara 0 dan 1
  2. MD5 menghitung jumlah MD5 dari (1), 32 karakter dari af dan 0-9
  3. UNHEX menerjemahkan (2) menjadi 16 byte dengan nilai dari 00 ke FF
  4. TO_BASE64 menyandikan (3) sebagai base64, 22 karakter dari az dan AZ dan 0-9 plus "/" dan "+", diikuti oleh dua "="
  5. ketiganya REPLACEmenghapus karakter "/", "+" dan "=" dari (4)
  6. LEFT mengambil 8 karakter pertama dari (5), ubah 8 menjadi yang lain jika Anda membutuhkan lebih banyak atau lebih sedikit karakter dalam string acak Anda
  7. LPADmenyisipkan nol di awal (6) jika kurang dari 8 karakter; sekali lagi, ubah 8 ke sesuatu yang lain jika perlu
Jan Uhlig
sumber
Hebat, persis seperti yang saya cari untuk membuat ID seperti token secara asli di MySQL
rabudde
4

I Menggunakan data dari kolom lain untuk menghasilkan "hash" atau string unik

UPDATE table_name SET column_name = Right( MD5(another_column_with_data), 8 )
Richard Fragiacomo
sumber
4

8 huruf dari alfabet - Semua huruf besar:

UPDATE `tablename` SET `tablename`.`randomstring`= concat(CHAR(FLOOR(65 + (RAND() * 25))),CHAR(FLOOR(65 + (RAND() * 25))),CHAR(FLOOR(65 + (RAND() * 25))),CHAR(FLOOR(65 + (RAND() * 25)))CHAR(FLOOR(65 + (RAND() * 25))),CHAR(FLOOR(65 + (RAND() * 25))),CHAR(FLOOR(65 + (RAND() * 25))),CHAR(FLOOR(65 + (RAND() * 25))));
TV-C-15
sumber
3

Jika Anda tidak memiliki id atau seed, seperti itu untuk daftar nilai di sisipkan:

REPLACE(RAND(), '.', '')
ekerner
sumber
2

Solusi sederhana dan efisien untuk mendapatkan string 10 karakter acak dengan huruf besar dan kecil serta angka:

select substring(base64_encode(md5(rand())) from 1+rand()*4 for 10);
Antares
sumber
1

Jika Anda setuju dengan pelat nomor "acak" tetapi sepenuhnya dapat diprediksi, Anda dapat menggunakan register geser umpan balik linier untuk memilih nomor pelat berikutnya - dijamin untuk melewati setiap nomor sebelum mengulang. Namun, tanpa matematika yang rumit, Anda tidak akan dapat melewati setiap string alfanumerik 8 karakter (Anda akan mendapatkan 2 ^ 41 dari 36 ^ 8 (78%) kemungkinan pelat). Untuk membuat ini mengisi ruang Anda lebih baik, Anda bisa mengecualikan surat dari piring (mungkin O), memberi Anda 97%.

τεκ
sumber
1

Dengan mempertimbangkan jumlah karakter yang Anda butuhkan, Anda akan memiliki peluang yang sangat kecil untuk menghasilkan dua pelat nomor yang persis sama. Jadi Anda mungkin bisa lolos dengan menghasilkan angka-angka di LUA.

Anda memiliki 36 ^ 8 pelat nomor unik yang berbeda (2.821.109.907.456, itu banyak), bahkan jika Anda sudah memiliki satu juta pelat nomor, Anda akan memiliki peluang yang sangat kecil untuk menghasilkan yang sudah Anda miliki, sekitar 0,000035%

Tentu saja, itu semua tergantung pada berapa banyak pelat nomor yang akan Anda buat.

Lawrence Andrews
sumber
Benar, saya akan terus melakukannya di game sebenarnya, bukan di SQL. Terima kasih banyak.
funstein
1

Fungsi ini menghasilkan string acak berdasarkan panjang input Anda dan karakter yang diizinkan seperti ini:

SELECT str_rand(8, '23456789abcdefghijkmnpqrstuvwxyz');

kode fungsi:

DROP FUNCTION IF EXISTS str_rand;

DELIMITER //

CREATE FUNCTION str_rand(
    u_count INT UNSIGNED,
    v_chars TEXT
)
RETURNS TEXT
NOT DETERMINISTIC
NO SQL
SQL SECURITY INVOKER
COMMENT ''
BEGIN
    DECLARE v_retval TEXT DEFAULT '';
    DECLARE u_pos    INT UNSIGNED;
    DECLARE u        INT UNSIGNED;

    SET u = LENGTH(v_chars);
    WHILE u_count > 0
    DO
      SET u_pos = 1 + FLOOR(RAND() * u);
      SET v_retval = CONCAT(v_retval, MID(v_chars, u_pos, 1));
      SET u_count = u_count - 1;
    END WHILE;

    RETURN v_retval;
END;
//
DELIMITER ;

Kode ini didasarkan pada fungsi string acak yang dikirim oleh "Ross Smith II"

Mahoor 13
sumber
Fungsi ini tidak akan menghasilkan nilai unik acak.
Faisal
1

Untuk membuat 10 digit alfanumerik acak , tidak termasuk karakter yang mirip 01oOlI:

LPAD(LEFT(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(TO_BASE64(UNHEX(MD5(RAND()))), "/", ""), "+", ""), "=", ""), "O", ""), "l", ""), "I", ""), "1", ""), "0", ""), "o", ""), 10), 10, 0)

Inilah yang saya butuhkan untuk membuat kode voucher . Karakter yang membingungkan dihapus untuk mengurangi kesalahan saat mengetiknya ke dalam formulir kode voucher.

Semoga ini bisa membantu seseorang, berdasarkan jawaban brilian Jan Uhlig .

Silakan lihat jawaban Jan untuk rincian tentang cara kerja kode ini.

Paul Harris
sumber
0
DELIMITER $$

USE `temp` $$

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 ;

Gunakan prosedur tersimpan ini dan gunakan setiap saat

Call GenerateUniqueValue('tableName','columnName')
Hariramprasath Nandhagopalan
sumber
0

Cara mudah yang menghasilkan nomor unik

set @i = 0;
update vehicles set plate = CONCAT(@i:=@i+1, ROUND(RAND() * 1000)) 
order by rand();
Gautier
sumber
0

Saya mencari sesuatu yang serupa dan saya memutuskan untuk membuat versi saya sendiri di mana Anda juga dapat menentukan benih yang berbeda jika diinginkan (daftar karakter) sebagai parameter:

CREATE FUNCTION `random_string`(length SMALLINT(3), seed VARCHAR(255)) RETURNS varchar(255) CHARSET utf8
    NO SQL
BEGIN
    SET @output = '';

    IF seed IS NULL OR seed = '' THEN SET seed = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; END IF;

    SET @rnd_multiplier = LENGTH(seed);

    WHILE LENGTH(@output) < length DO
        # Select random character and add to output
        SET @output = CONCAT(@output, SUBSTRING(seed, RAND() * (@rnd_multiplier + 1), 1));
    END WHILE;

    RETURN @output;
END

Dapat digunakan sebagai:

SELECT random_string(10, '')

Yang akan menggunakan benih bawaan dari karakter huruf besar dan kecil + digit. NULL juga akan menjadi nilai, bukan ''.

Tetapi seseorang dapat menentukan benih khusus saat memanggil:

SELECT random_string(10, '1234')
Maarten Ureel
sumber