number - mssql random 범위




T-SQL에서 새로운 고유 난수 목록 생성 (2)

고유 한 임의의 8 자리 숫자가있는 @n 레코드를 생성하는 저장 프로 시저가 필요합니다. 이 숫자는 증분이 아니어야하며 테이블에 이미 존재하지 않아야합니다.

CREATE TABLE Codes
(
    ID UNIQUEIDENTIFIER PRIMARY KEY,
    Code INT,
    CONSTRAINT UQ_Code UNIQUE(Code) 
);

난 임의의 숫자를 생성 할 수 있습니다 :

DECLARE @min int = 0,
        @max int = 99999999,
        @n INT = 100;

SELECT TOP (@n) FLOOR(CAST(CRYPT_GEN_RANDOM(4) AS BIGINT) / 4294967296 * ((@max - @min) + 1)) + @min
FROM   sys.all_objects s1 
              CROSS JOIN sys.all_objects s2;

하지만 내가 알아 내려고 애 쓰고있는 것은 충돌을 피하기 위해 [Codes] 테이블에 @n 숫자를 원자 적으로 생성하고 삽입하는 방법입니다. 루프없이이 작업을 수행 할 수 있습니까?

최신 정보
"must not be incremental" 말은 SP 대한 각 호출에 대해 "1, 2, 3, 4" 또는 다른 공통 패턴을 반환하지 않기를 의미합니다. 나는 모든 값을 소비 할 수 있어야하므로 궁극적으로 증분 값이 존재하지만 순차적으로가 아니라 서로 다른 시점에서 생성됩니다.


계산 된 코드 인 distinct 와 함께 cte를 사용하고 코드가 이미 테이블에 있는지 확인하십시오.

;with cte_stream as (
    select
        floor(cast(crypt_gen_random(4) as bigint) / 4294967296 * ((@max - @min) + 1)) + @min as Code
    from sys.all_objects as s1 
        cross join sys.all_objects as s2;
)
insert into [Codes]
select distinct top (@n) s.Code
from cte_stream as s
where not exists (select * from [Codes] as c where c.Code = s.Code)

그래서 distinct 는 새로운 코드 간의 충돌을 피하는 데 도움이되며 [Codes] 테이블의 기존 코드와의 충돌을 피하는 데 도움이 order by newid() 은 새 코드에서 임의의 값을 가져 오는 데 도움이됩니다.


이것을 시도 할 수 있습니다 :

    DECLARE @min int = 0,
        @max int = 99999999,
        @n INT = 100;

Insert Into Codes(ID, Code)
SELECT G, RandomNumber
From (
    Select TOP (@n) NEWID() As G, FLOOR(CAST(CRYPT_GEN_RANDOM(4) AS BIGINT) / 4294967296 * ((@max - @min) + 1)) + @min As RandomNumber
    FROM   sys.all_objects s1 
                  CROSS JOIN sys.all_objects s2) AS Ran
Where RandomNumber Not IN (Select Code From Codes);

편집 : 기존 코드를 피하기 위해 where 조건을 추가했습니다.





sql-server-2012