[sql] T-SQL로 임의 문자열 생성

T-SQL을 사용하여 의사 난수 영숫자 문자열을 생성하려면 어떻게 하시겠습니까? 달러 기호, 대시 및 슬래시와 같은 문자를 어떻게 제외 하시겠습니까?



답변

특히 테스트를 위해 무작위 데이터를 생성 할 때 데이터를 무작위로 만들지 만 재현 가능하게 만드는 것이 매우 유용합니다. 비결은 랜덤 함수에 명시 적 시드를 사용하여 동일한 시드로 테스트를 다시 실행할 때 정확히 동일한 문자열을 다시 생성하도록하는 것입니다. 다음은 재현 가능한 방식으로 객체 이름을 생성하는 함수의 간단한 예입니다.

alter procedure usp_generateIdentifier
    @minLen int = 1
    , @maxLen int = 256
    , @seed int output
    , @string varchar(8000) output
as
begin
    set nocount on;
    declare @length int;
    declare @alpha varchar(8000)
        , @digit varchar(8000)
        , @specials varchar(8000)
        , @first varchar(8000)
    declare @step bigint = rand(@seed) * 2147483647;

    select @alpha = 'qwertyuiopasdfghjklzxcvbnm'
        , @digit = '1234567890'
        , @specials = '_@# '
    select @first = @alpha + '_@';

    set  @seed = (rand((@seed+@step)%2147483647)*2147483647);

    select @length = @minLen + rand(@seed) * (@maxLen-@minLen)
        , @seed = (rand((@seed+@step)%2147483647)*2147483647);

    declare @dice int;
    select @dice = rand(@seed) * len(@first),
        @seed = (rand((@seed+@step)%2147483647)*2147483647);
    select @string = substring(@first, @dice, 1);

    while 0 < @length 
    begin
        select @dice = rand(@seed) * 100
            , @seed = (rand((@seed+@step)%2147483647)*2147483647);
        if (@dice < 10) -- 10% special chars
        begin
            select @dice = rand(@seed) * len(@specials)+1
                , @seed = (rand((@seed+@step)%2147483647)*2147483647);
            select @string = @string + substring(@specials, @dice, 1);
        end
        else if (@dice < 10+10) -- 10% digits
        begin
            select @dice = rand(@seed) * len(@digit)+1
                , @seed = (rand((@seed+@step)%2147483647)*2147483647);
            select @string = @string + substring(@digit, @dice, 1);
        end
        else -- rest 80% alpha
        begin
            declare @preseed int = @seed;
            select @dice = rand(@seed) * len(@alpha)+1
                , @seed = (rand((@seed+@step)%2147483647)*2147483647);

            select @string = @string + substring(@alpha, @dice, 1);
        end

        select @length = @length - 1;   
    end
end
go

테스트를 실행할 때 호출자는 테스트 실행과 관련된 임의의 시드를 생성 한 다음 (결과 테이블에 저장) 다음과 유사하게 시드를 따라 전달합니다.

declare @seed int;
declare @string varchar(256);

select @seed = 1234; -- saved start seed

exec usp_generateIdentifier 
    @seed = @seed output
    , @string = @string output;
print @string;  
exec usp_generateIdentifier 
    @seed = @seed output
    , @string = @string output;
print @string;  
exec usp_generateIdentifier 
    @seed = @seed output
    , @string = @string output;
print @string;  

2016-02-17 업데이트 : 아래의 설명을 참조하십시오. 원래 절차에는 무작위 시드를 진행하는 방식에 문제가있었습니다. 코드를 업데이트하고 언급 된 개별 문제도 수정했습니다.


답변

GUID 사용

SELECT @randomString = CONVERT(varchar(255), NEWID())

매우 짧은 …


답변

첫 번째 예와 유사하지만 더 많은 유연성이 있습니다.

-- min_length = 8, max_length = 12
SET @Length = RAND() * 5 + 8
-- SET @Length = RAND() * (max_length - min_length + 1) + min_length

-- define allowable character explicitly - easy to read this way an easy to 
-- omit easily confused chars like l (ell) and 1 (one) or 0 (zero) and O (oh)
SET @CharPool = 
    'abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ23456789.,-_!$@#%^&*'
SET @PoolLength = Len(@CharPool)

SET @LoopCount = 0
SET @RandomString = ''

WHILE (@LoopCount < @Length) BEGIN
    SELECT @RandomString = @RandomString + 
        SUBSTRING(@Charpool, CONVERT(int, RAND() * @PoolLength), 1)
    SELECT @LoopCount = @LoopCount + 1
END

나는 이것을 더 유연하게 만드는 다른 기능 중 하나를 언급하는 것을 잊었습니다. @CharPool에서 문자 블록을 반복하여 특정 문자에 대한 가중치를 증가시켜 선택 가능성을 높일 수 있습니다.


답변

다음 코드를 사용하여 짧은 문자열을 반환합니다.

SELECT SUBSTRING(CONVERT(varchar(40), NEWID()),0,9)


답변

SQL Server 2008 이상을 실행하는 경우 새 암호화 함수 crypt_gen_random ()을 사용한 다음 base64 인코딩을 사용하여 문자열로 만들 수 있습니다. 최대 8000 자까지 작동합니다.

declare @BinaryData varbinary(max)
    , @CharacterData varchar(max)
    , @Length int = 2048

set @BinaryData=crypt_gen_random (@Length)

set @CharacterData=cast('' as xml).value('xs:base64Binary(sql:variable("@BinaryData"))', 'varchar(max)')

print @CharacterData


답변

저는 T-SQL 전문가는 아니지만 이미 사용한 가장 간단한 방법은 다음과 같습니다.

select char((rand()*25 + 65))+char((rand()*25 + 65))

이렇게하면 두 개의 문자 (AZ, ascii 65-90)가 생성됩니다.


답변

select left(NEWID(),5)

이것은 guid 문자열에서 가장 왼쪽에있는 5 개의 문자를 반환합니다.

Example run
------------
11C89
9DB02