MySQL을 사용하여 임의의 고유 한 8 자 문자열 생성


110

나는 어느 시점에서 차량과 관련된 게임을 작업하고 있습니다. 차량에 대한 번호판을 저장하는 "plate"열을 포함하여 차량에 대한 데이터를 포함하는 "vehicles"라는 MySQL 테이블이 있습니다.

이제 제가 문제가있는 부분이 있습니다. 새 차량을 만들기 전에 사용하지 않은 번호판을 찾아야합니다. 영숫자 8 자로 된 임의의 문자열이어야합니다. 내가 이것을 달성 한 방법은 내가 프로그래밍하는 언어 인 Lua에서 while 루프를 사용하여 문자열을 생성하고 DB를 쿼리하여 사용 여부를 확인하는 것이 었습니다. 하지만 차량 수가 늘어남에 따라 지금보다 훨씬 비효율적 일 것으로 예상됩니다. 따라서 MySQL 쿼리를 사용하여이 문제를 해결하기로 결정했습니다.

필요한 쿼리는 테이블에 아직없는 8 자 영숫자 문자열을 생성해야합니다. 다시 생성 및 확인 루프 접근 방식을 생각했지만 더 효율적인 질문이있는 경우에만이 질문을 제한하지 않습니다. 허용 된 모든 문자를 포함하는 문자열을 정의하고 임의로 하위 문자열을 지정하여 문자열을 생성 할 수있었습니다.

도움을 주시면 감사하겠습니다.


이것들이 얼마나 무작위로 필요합니까? 누군가 특정 번호판을 받았다면, 당신이 나눠준 다음 번호판이나 이전 번호판을 알아낼 수 있는지 여부가 중요합니까?
Damien_The_Unbeliever

@YaK 충돌의 작은 가능성도 피하는 방법에 대한 내 대답보기
Eugen Rieck

답변:


87

이 문제는 매우 다른 두 가지 하위 문제로 구성됩니다.

  • 문자열은 겉보기에는 무작위로 보여야합니다.
  • 문자열은 고유해야합니다.

임의성은 매우 쉽게 얻을 수 있지만 재시도 루프가없는 고유성은 그렇지 않습니다. 이것은 우리가 먼저 독창성에 집중하게합니다. 무작위가 아닌 고유성은 AUTO_INCREMENT. 따라서 고유성을 유지하는 의사 랜덤 변환을 사용하는 것이 좋습니다.

  • @paul이 해시를 제안했습니다.
  • AES 암호화도 적합합니다.
  • 그러나 좋은 것이 있습니다 : RAND(N)그 자체입니다!

동일한 시드로 생성 된 일련의 난수는

  • 재생할 수 있는
  • 처음 8 회 반복에 대해 다름
  • 씨앗이 INT32

그래서 우리는 @AndreyVolk 또는 @GordonLinoff의 접근 방식을 사용하지만 시드가 있습니다 RAND .

예를 들어 Assumin idAUTO_INCREMENT열입니다.

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;

매우 흥미로운 접근 방식이지만 아마도 의미했을 것입니다 RAND(LAST_INSERT_ID()); UPDATE vehicles (...) , rand()*36+1, (...)(또는 그렇지 않으면 동일한 문자의 8 배를 반환합니다). rand()다른 시드로 초기화 된 경우 8 개의 연속 호출 이 다른 시퀀스를 반환하도록 보장하려면 어떻게해야합니까?
RandomSeed

8
나는 단지 궁금했다. 왜 그 숫자를 사용합니까 ..4294967296)) * 36 + 1?
Mick

7
이것은 약간 오래되었지만 FLOOR()두 번째 하위 문자열 매개 변수 주위 에 추가해야했습니다 . substring('ABC … 789', floor(rand(@seed:= … )*36+1), 1), 어떤 경우에는 하위 문자열이 문자 36.9를 선택하려고했는데, 37로 반올림하면 문자가 선택되지 않습니다.
Phillip Dodson

4
재현 가능한 경우 문자열을 무작위로 호출 할 수 없습니다. 을 사용하고 있기 때문에 중복도 가능합니다 floor(). 이 sqlfiddle 은 세 문자의 긴 문자열에 대해 중복이 생성 되었음을 보여줍니다.
Paul Spiegel 2016 년

6
@EugenRieck 나는 당신이 당신의 숫자를 얻는 방법을 이해하지 못합니다 ( "처음 2 ^ 32 반복"). 하지만이 개념을 반증하기 위해서는 중복 사례가 하나만 필요합니다. ID 193844775771알고리즘에 대해 동일한 문자열 T82X711( demo )을 생성합니다 .
Paul Spiegel

113

내 의견에서 언급했듯이 충돌 가능성에 대해서는 신경 쓰지 않습니다. 임의의 문자열을 생성하고 존재하는지 확인하십시오. 만약 그렇다면, 다시 시도하세요. 이미 많은 수의 플레이트가 할당되어 있지 않는 한 두 번 더 할 필요가 없습니다.

순수 (My) SQL에서 8 자 길이의 의사 랜덤 문자열을 생성하는 또 다른 솔루션 :

SELECT LEFT(UUID(), 8);

다음 (의사 코드)을 시도 할 수 있습니다.

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

이 게시물이 예상치 못한 수준의 관심을 받았으므로 ADTC의 의견을 강조 하겠습니다 . 위의 코드는 매우 멍청하고 연속적인 숫자를 생성합니다.

약간 덜 어리석은 무작위성을 위해 대신 다음과 같이 시도하십시오.

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

그리고 진정한 (암호 화학적으로 안전한) 임의성을 위해 RANDOM_BYTES()대신 사용하십시오 RAND()(하지만이 논리를 애플리케이션 계층으로 이동하는 것을 고려할 것입니다).


귀하의 솔루션에 감사드립니다. UUID와 관련하여 한 가지 질문이 있습니다. 생성 한 아이디가 8 자 반복 될 확률
TR-Ahmed

1
@ user3099183 공식적 으로 "매우 낮음"입니다. 16 ^ 8은 약 40 억 개의 가능한 문자열입니다.
RandomSeed 2014-08-20

23
UUID의 처음 8자는 타임 스탬프를 기반으로하기 때문에 무작위가 아니라 순차적이라는 점에 유의하십시오.
ADTC

9 자 길이의 임의 문자열을 생성하고 싶습니다. 9코드에서 사용할 때 SELECT LEFT(UUID(), 9);항상 -생성 된 문자열의 끝에 아홉 번째 문자가 있습니다. 그것은 일정합니다. 왜?
Martin AJ

3
@MartinAJ는 문자열이 uuid 이기 때문 입니다. 당신은 쉽게 하이픈 예를 대체 할 수있다SELECT LEFT(REPLACE(UUID(), '-', ''), 16);
jchook

53

순차 정수의 MD5 (또는 기타) 해시를 계산 한 다음 처음 8자를 사용하는 것은 어떻습니까?

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

기타

주의 : 충돌 전에 얼마나 많은 것을 할당 할 수 있는지 모르겠습니다 (하지만 알고 있고 일정한 값이 될 것입니다).

편집 : 이것은 이제 오래된 대답이지만 시간이 지남에 따라 다시 보았으므로 관찰에서 ...

모든 숫자의 확률 = 2.35 %

모든 글자의 확률 = 0.05 %

MD5 (82945) = "7b763dcb ..."일 때 첫 번째 충돌 (MD5 (25302)과 동일한 결과)


2
좋은 생각, 기본 키에 사용할 수 있습니다. 향후 프로젝트를 위해 이것을 염두에 둘 것입니다. 감사합니다!
funstein

2
이것이 숫자로만
나타날

9
전혀 무작위가 아닙니다.
Paul

1
자동 증분 ID를 사용하는 대신 삽입이 수행 된 날짜 / 시간을 사용하면 더 "무작위"로 만들 수 있습니다.
Javier La Banca

35

임의의 문자열 만들기

다음은 주어진 길이의 임의의 문자열을 생성하는 MySQL 함수입니다.

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

SELECT RANDSTRING(8)8 자 문자열을 반환하는 데 사용 됩니다.

당신은 사용자 정의 할 수 있습니다 @allowedChars.

고유성이 보장되지는 않습니다. 다른 솔루션에 대한 의견에서 볼 수 있듯이 이것은 불가능합니다. 대신 문자열을 생성하고 이미 사용 중인지 확인한 다음 사용중인 경우 다시 시도해야합니다.


임의의 문자열이 이미 사용 중인지 확인하십시오.

앱에서 충돌 검사 코드를 유지하려면 트리거를 만들 수 있습니다.

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 ;

6
이 명확 허용 대답하고 점에, 나를 위해 잘 덕분에 일을해야 @ 논 - MANN
사이프

이것이 제가 생각하는 최고의 솔루션입니다. 감사합니다!
Pronoy999

23

다음은 영숫자를 유효한 문자로 사용하는 한 가지 방법입니다.

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;

고유성을 보장하지 않습니다. 별도로 확인해야합니다.


7
대신 floor (rand () * 36 + 1)을 사용하십시오. 그렇지 않으면 일부 결과가 '짧은'것입니다.
Fraggle

2
36 + 1이 아닌 35 + 1이 있어야합니다! 그렇지 않으면 7 8 개 문자 그들 중 일부 일부 일부 문자열을 얻을 것이다
생물학적 위험

23

다음은 임의의 문자열을 생성하는 또 다른 방법입니다.

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


16

MySQL의 rand ()char () 함수를 사용할 수 있습니다 .

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;

14

다음을 사용하여 임의의 영숫자 문자열을 생성 할 수 있습니다.

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

BEFORE INSERT트리거에서 사용하고 while 루프에서 중복을 확인할 수 있습니다 .

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 ;

이제 다음과 같이 데이터를 삽입하십시오.

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

그리고 트리거는 plate열에 대한 값을 생성합니다 .

( sqlfiddle 데모 )

열이 NULL을 허용하는 경우 이러한 방식으로 작동합니다. NOT NULL이되도록하려면 기본값을 정의해야합니다.

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

대문자 영숫자가 원하는 것이 아닌 경우 트리거에서 다른 임의의 문자열 생성 알고리즘을 사용할 수도 있습니다. 그러나 방아쇠는 고유성을 처리합니다.


놀랄 만한! 이것이 바로 제가 원했던 것입니다. 나는 그것이 어떻게 문자열로 변환되는지 이해하고 싶습니다. 왜 포로가 있고, 무엇을해야하는지, 숫자를 더하는 것 등이 있습니다. 어쨌든 감사합니다.
Akxe

@Akxe conv () 는 숫자를 영숫자 문자열로 변환하는 데 사용할 수 있습니다.pow(36,8)-1의 숫자 표현입니다 ZZZZZZZZ. 그래서 우리는 0~ '36 ^ 8-1 '(부터 0~까지 2821109907455) 사이의 임의의 정수를 생성하고 그것을 ~ 0ZZZZZZZZunsing 사이의 영숫자 문자열로 변환합니다 conv(). 파드는 () 가 (8)의 길이가 될 때까지 0으로 문자열을 채울 것입니다
폴 스피겔

당신은 천재입니다. 문자의 연속성이 없어서 소문자를 추가하는 것이 불가능하다고 생각합니다. (91-96) 내가 필요로하는 것이 아니라 호기심 만 ...
Akxe

@Akxe conv()는 최대 36 자 (10 자리 + 대문자 26 자)까지만 지원합니다. 소문자를 포함하려면 숫자를 문자열로 변환하는 다른 방법이 필요합니다.
Paul Spiegel 2017

주의 사항 : str_len> 13에서는 작동하지 않습니다. 14부터는 항상 '3W5E11264SGSF'를 얻습니다. ;-)
Gerard H. Pille

6

임의의 문자열을 생성하려면 다음을 사용할 수 있습니다.

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

당신은 다음과 같은 것을받습니다.

353E50CC


5

8 개의 난수와 대문자 및 소문자로 구성된 문자열의 경우 이것이 내 솔루션입니다.

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

내부에서 설명 :

  1. RAND 0과 1 사이의 난수를 생성합니다.
  2. MD5 (1)의 MD5 합계, af 및 0-9에서 32 자 계산
  3. UNHEX (2)를 00에서 FF까지의 값을 가진 16 바이트로 변환합니다.
  4. TO_BASE64 (3)을 base64로 인코딩하고, az 및 AZ의 22 자, 0-9에 "/"및 "+"를 더한 다음 "="2 개를 추가합니다.
  5. REPLACE s는 (4)에서 "/", "+"및 "="문자를 제거합니다.
  6. LEFT (5)에서 처음 8자를 취하고 임의의 문자열에 더 많거나 적은 문자가 필요한 경우 8을 다른 것으로 변경하십시오.
  7. LPAD길이가 8 자 미만인 경우 (6) 시작 부분에 0을 삽입합니다. 다시, 필요한 경우 8을 다른 것으로 변경하십시오.

훌륭합니다. MySQL에서 기본적으로 토큰과 유사한 ID를 생성하기 위해 찾던 것입니다
rabudde

4

다른 열의 데이터를 사용하여 "해시"또는 고유 한 문자열을 생성합니다.

UPDATE table_name SET column_name = Right( MD5(another_column_with_data), 8 )

4

알파벳 8 자-모두 대문자 :

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))));

3

삽입의 값 목록과 같은 ID 또는 시드가없는 경우 :

REPLACE(RAND(), '.', '')

2

대문자, 소문자 및 숫자가 포함 된 임의의 10 자 문자열을 얻는 간단하고 효율적인 솔루션 :

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

1

"무작위"이지만 완전히 예측 가능한 번호판은 괜찮다면 선형 피드백 시프트 레지스터 를 사용하여 다음 번호판 번호를 선택할 수 있습니다. 반복하기 전에 모든 번호를 통과하는 것이 보장됩니다. 그러나 복잡한 수학 없이는 8 개의 영숫자 문자열을 모두 통과 할 수 없습니다 (36 ^ 8 (78 %) 가능한 플레이트에서 2 ^ 41을 얻습니다). 공간을 더 잘 채우려면 번호판에서 문자 (아마도 O)를 제외하여 97 %를 얻을 수 있습니다.


1

필요한 총 문자 수를 고려하면 정확히 유사한 두 개의 번호판을 생성 할 가능성이 매우 적습니다. 따라서 LUA에서 숫자를 생성하는 것에서 벗어날 수 있습니다.

36 ^ 8 개의 서로 다른 고유 번호판 (2,821,109,907,456 개)이 있습니다. 이미 백만 개의 번호판이 있더라도 이미 가지고있는 번호판을 생성 할 가능성은 매우 적습니다. 약 0.000035 %

물론, 그것은 모두 당신이 생성하게 될 번호판의 수에 달려 있습니다.


사실, SQL 대신 실제 게임에서 계속할 것입니다. 대단히 감사합니다.
funstein

1

이 함수는 입력 길이와 다음과 같이 허용되는 문자를 기반으로 임의 문자열을 생성합니다.

SELECT str_rand(8, '23456789abcdefghijkmnpqrstuvwxyz');

기능 코드 :

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 ;

이 코드는 "Ross Smith II"에서 보내는 셔플 문자열 기능을 기반으로 합니다.


이 함수는 임의의 고유 값을 생성하지 않습니다.
파이살 19

1

유사 문자 01oOlI를 제외하고 임의의 10 자리 영숫자 를 만들려면 다음을 수행하십시오.

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)

이것이 바로 바우처 코드 를 만드는 데 필요한 것 입니다. 바우처 코드 양식에 입력 할 때 오류를 줄이기 위해 혼란스러운 문자가 제거됩니다.

Jan Uhlig의 훌륭한 답변을 기반으로 누군가에게 도움이 되기를 바랍니다 .

이 코드의 작동 방식에 대한 자세한 내용은 Jan의 답변을 참조하십시오.


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 ;

이 저장 프로 시저를 사용하고 다음과 같이 매번 사용하십시오.

Call GenerateUniqueValue('tableName','columnName')

0

고유 번호를 생성하는 쉬운 방법

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


0

비슷한 것을 찾고 있었고 원하는 경우 다른 시드 (문자 목록)를 매개 변수로 지정할 수도있는 내 버전을 만들기로 결정했습니다.

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

다음과 같이 사용할 수 있습니다.

SELECT random_string(10, '')

내장 된 대문자 및 소문자 + 숫자를 사용합니다. NULL도 ''대신 값이됩니다.

그러나 호출하는 동안 사용자 지정 시드를 지정할 수 있습니다.

SELECT random_string(10, '1234')
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.