2012-02-16 2 views
-1
SELECT CRYPT_GEN_RANDOM(4) as SAMPLEDATA 

для каждого выбора выше функция генерирует некоторое случайное значение буквенно-цифровой, но некоторое время он был генерации специальных символов, кроме того, в таком случае, как я могу я избежать специальные символы с использованием хранимой процедуры sqlфильтр из «специальных» символов из CRYPT_GEN_RANDOM()

+0

Что вы хотите, чтобы ваши случайные персонажи были? Простой ASCII = A-Z/a-z/0-9 и т. Д.? Я думаю, что CRYPT_GEN_RANDOM - неправильный подход. –

+1

"вышеуказанная функция генерирует некоторое случайное значение буквенно-цифровой" - нет, она не будет генерировать [шестнадцатеричное число указанного числа (4, здесь) байтов] (http://msdn.microsoft.com /en-us/library/cc627408.aspx). Что вы на самом деле пытаетесь сделать? – AakashM

ответ

0

CRYPT_GEN_RANDOM() генерирует varbinary, который не хорошо переводит текст.

Если вы просто хотите случайное буквенно-цифровое значение, вы можете использовать что-то вроде GUID, используя NEWID(), чтобы получить тот же эффект.

0

Заимствование из идеи @ JNK. Предполагая, что вы на самом деле после того, как буквенно-цифровые только, что дело не имеет значения, и самая длинная строка вам нужно, это 36 символов, вы можете сначала создать вид:

CREATE VIEW dbo.RetrieveNewID 
AS 
    SELECT [NewID] = NEWID(); 
GO 

Затем создайте эту функцию:

CREATE FUNCTION dbo.GenerateRandomNumbersLetters 
(
    @NumberOfCharacters TINYINT 
) 
RETURNS VARCHAR(32) 
AS 
BEGIN 
    RETURN 
    (
     SELECT LEFT(REPLACE([NewID], '-', ''), @NumberOfCharacters) 
     FROM dbo.RetrieveNewID 
    ); 
END 
GO 

Мои результаты:

SELECT r = dbo.GenerateRandomNumbersLetters(4); 
SELECT r = dbo.GenerateRandomNumbersLetters(4); 
SELECT r = dbo.GenerateRandomNumbersLetters(4); 

r 
---- 
EA93 
9D32 
B229 

Это будет хорошо, если вы делаете это в режиме onesy-twosy. Если вы пытаетесь сгенерировать эту функцию для набора, она становится менее эффективной по мере увеличения набора. Пример:

SELECT r = dbo.GenerateRandomNumbersLetters(i) FROM 
(
    SELECT i = 1 
    UNION ALL SELECT i = 2 
    UNION ALL SELECT i = 3 
) AS x; 

Я не ожидаю, что это будет особенно хорошо работать с большим набором данных.


Теперь, если вы хотите использовать символы, которые вне множества возможно в GUID (A-Z/0-9), вы можете сделать это с помощью таблицы. Предполагая, что в этом же представлении выше, мы можем создать таблицу и наполнить ее любыми символами, которые хотим быть доступными для случайного генератора (который включает символы за пределами строгих буквенно-цифровых символов, но все равно могут исключать любые «специальные» символы, которые вы не хотите рассматривать).

CREATE TABLE dbo.RandomCharacters 
(
    Digit NVARCHAR(1) COLLATE Latin1_General_CS_AI PRIMARY KEY 
); 

;WITH x AS 
(
    SELECT TOP (200) i = ROW_NUMBER() OVER (ORDER BY [object_id]) 
    FROM sys.all_objects 
    ORDER BY [object_id] 
) 
INSERT dbo.RandomCharacters 
SELECT NCHAR(i) FROM x 
WHERE (i BETWEEN 65 AND 90) -- A-Z 
    OR (i BETWEEN 97 AND 122) -- a-z 
    OR (i BETWEEN 48 AND 57) -- 0-9 
    OR (i IN (42, 126, 181)); -- *, ~, µ 

Теперь функция, которая делает волшебство (опять же это все зависит от трюка, который позволяет нам ссылаться на NEWID() в функции, скрывая его в представлении):

CREATE FUNCTION dbo.GenerateRandomCharacters 
(
    @NumberOfCharacters TINYINT 
) 
RETURNS NVARCHAR(255) 
AS 
BEGIN 
    RETURN 
    (
     SELECT (SELECT x.Digit FROM (
      SELECT TOP (@NumberOfCharacters) r.Digit 
      FROM dbo.RandomCharacters AS r 
      CROSS JOIN dbo.RetrieveNewID AS d 
      ORDER BY CONVERT(VARBINARY(36), d.[NewID]) 
     ) AS x 
     FOR XML PATH(''), TYPE).value('.[1]','nvarchar(max)') 
    ); 
END 
GO 

Мои результаты:

SELECT r = dbo.GenerateRandomCharacters(4); 
SELECT r = dbo.GenerateRandomCharacters(4); 
SELECT r = dbo.GenerateRandomCharacters(4); 

r 
---- 
H~1r 
Dfn2 
µHxF 

В этом последнем решении дубликаты не поддерживаются. Я также не ожидаю, что производительность будет впечатляющей в больших наборах данных. Но вы можете иметь более 32 символов. :-)

Смежные вопросы