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

每選字符上述功能意願生成字母數字的一些隨機值,但有些時候它產生特殊字符也,在這種情況下我如何可以我避免使用sql存儲過程生成的特殊字符篩選出「特殊」從CRYPT_GEN_RANDOM()

+0

你想要隨機字符是什麼?簡單的ASCII = A-Z/a-z/0-9等?我認爲CRYPT_GEN_RANDOM是錯誤的方法。 – 2012-02-16 14:31:45

+1

「上面的函數會生成一些隨機的字母數字值」 - 不會,它會生成[一個十六進制數的指定數字(這裏是4字節)](http://msdn.microsoft.com /en-us/library/cc627408.aspx)。你究竟在做什麼? – AakashM 2012-02-16 14:41:45

回答

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個字符。 :-)