Генерация случайных значений из SQL - PullRequest
1 голос
/ 06 ноября 2008

Похоже, что SQL Server, как и большинство других продуктов, не является случайным. Итак, у нас есть эта милая маленькая функция для генерации значения 10 символов. Есть ли лучший способ сделать то, что делает следующее. Держу пари, что есть.

DECLARE @SaltCount INT;
SELECT @SaltCount = COUNT(*) FROM tmp_NewLogin;
PRINT 'Set Salt values for all records' + CAST(@SaltCount AS VARCHAR(10))
DECLARE @CharPool CHAR(83);
DECLARE @Salt VARCHAR(10);
SET @CharPool = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!"#$%&()*+,-./:;<=>?@';

SET NOCOUNT ON;
updateSaltValue:
    SET @Salt = ''
    SELECT @Salt = @Salt + SUBSTRING(@CharPool, number, 1) FROM
    (
    SELECT TOP 10 number FROM MASTER..[spt_values] WHERE TYPE = 'p' AND Number BETWEEN 1 AND 83
    ORDER BY NEWID()
    ) AS t

    UPDATE TOP(1) [table] SET [Salt] = @Salt WHERE [Salt] IS NULL

IF (@@ROWCOUNT > 0)
    GOTO updateSaltValue

SET NOCOUNT OFF;

PRINT 'Completed setting salts for all records';

Ответы [ 6 ]

9 голосов
/ 06 ноября 2008

Большинство программистов совершают ошибку, заново изобретая функциональность рандомизации, и в итоге получают нечто совершенно не случайное. Я бы порекомендовал вам придерживаться встроенной функции RAND (). Запустите один раз и получите столько значений, сколько вам нужно.

3 голосов
/ 06 ноября 2008

Reinventing RAND - это рецепт катастрофы. Где вы когда-нибудь замечали, что он ведет себя неправильно? Я не думаю, что вам даже нужно посеять это. SQL Server должен заполнить его сам по себе, просто отлично. Заполнение должно быть просто необходимым, когда вам нужно произвести одну и ту же «случайную» последовательность несколько раз при тестировании алгоритмов или чего-то подобного.

1 голос
/ 07 ноября 2008

Используйте функцию Rand () .... и начните ее с чего-то другого, случайного, такого как количество миллисекунд в текущей sysDate или текущей метке времени ... Или вызовом функции NewId () ...

1 голос
/ 06 ноября 2008

В соответствии с интерактивными книгами для функции rand (): если seed не указан, ядро ​​базы данных Microsoft SQL Server 2005 назначает начальное значение случайным образом Для указанного начального значения возвращаемый результат всегда одинаков.
Вы можете избежать этого с помощью быстрого и грязного трюка:

  1. Создать вид, подобный этому:

    create view [dbo].[wrapped_rand_view]
    as
    select rand( ) as random_value
    
  2. Следующая функция создания, которая читает из представления:

    create function [dbo].[wrapped_rand]()
    returns float
    as
    begin
    declare @f float
    set @f = (select random_value from wrapped_rand_view)
    return @f
    

Таким образом, вы получаете случайное начальное число каждый раз, когда вызываете функцию wrapped_rand (), и различное случайное значение от 0 до 1.

0 голосов
/ 27 ноября 2011

Иногда возникает необходимость сбросить пароль с помощью временного пароля или сгенерировать случайный пароль для нового пользователя.

Следующая хранимая процедура создает строки случайных символов на основе четырех параметров, которые конфигурируют результат.

> create proc [dbo].uspRandChars
>     @len int,
>     @min tinyint = 48,
>     @range tinyint = 74,
>     @exclude varchar(50) = '0:;<=>?@O[]`^\/',
>     @output varchar(50) output as 
>     declare @char char
>     set @output = ''
>  
>     while @len > 0 begin
>        select @char = char(round(rand() * @range + @min, 0))
>        if charindex(@char, @exclude) = 0 begin
>            set @output += @char
>            set @len = @len - 1
>        end
>     end
0 голосов
/ 06 ноября 2008

Не полная случайность алфавита, а случайность:

select substring(replace(newid(),'-',''),0,10)

Редактировать: Из комментариев я узнал, что newid () не очень хорош для случайности, особенно в сочетании с подстрокой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...