2012-10-11 105 views

回答

1

輕微修改的original

DECLARE @Numbers TABLE 
(
n INT PRIMARY KEY 
); 


WITH E00(N) AS (SELECT 1 UNION ALL SELECT 1), --2 
     E02(N) AS (SELECT 1 FROM E00 a, E00 b), --4 
     E04(N) AS (SELECT 1 FROM E02 a, E02 b), --16 
     E08(N) AS (SELECT 1 FROM E04 a, E04 b), --256 
     E16(N) AS (SELECT 1 FROM E08 a, E08 b) --65,536 
INSERT INTO @Numbers 
SELECT TOP 1000 ROW_NUMBER() OVER (ORDER BY (SELECT 0)) 
FROM E16 

/* 
1. Build a table variable of numbers 
2. For each row in the table (up to row 1000) 
3. Get the top 2 numbers from the table variable 
4. For each number, get the absolute value of the checksum of a GUID 
5. This value will always be a positive integer 
6. Get the remainder of that integer when divided by 26 
7. This will always be a number between 0 and 25 
8. If the absolute value number is divisible by 2, add 65 to the number (uppercase) 
9. Otherwise, add 97 to the number (lowercase) 
10. Use that number as an ASCII value and get the character representation 
11. Use FOR XML PATH to convert the two characters in the subquery to a string 
12. Repeat the same logic for 2 numbers (use %9 to get two numbers between 0 and 9) 
13. Repeat the same logic from previous steps to get two more alphabetic characters 
*/ 

SELECT CAST((SELECT TOP 2 CHAR(CASE 
            WHEN Abs(Checksum(Newid()))%2 = 0 THEN 65 
            ELSE 97 
           END + Abs(Checksum(Newid()))%26) 
      FROM @Numbers n1 
      WHERE n1.n >= -n2.n 
      FOR XML PATH('')) AS CHAR(2)) + 
     CAST((SELECT TOP 2 Abs(Checksum(Newid()))%9 
      FROM @Numbers n1 
      WHERE n1.n >= -n2.n 
      FOR XML PATH('')) AS CHAR(2)) +    
     CAST((SELECT TOP 2 CHAR(CASE 
            WHEN Abs(Checksum(Newid()))%2 = 0 THEN 65 
            ELSE 97 
           END + Abs(Checksum(Newid()))%26) 
      FROM @Numbers n1 
      WHERE n1.n >= -n2.n /*So it gets re-evaluated for each row!*/ 
      FOR XML PATH('')) AS CHAR(2)) 
FROM @Numbers n2 
+0

謝謝8kb - 這很好地訣竅 – Paul

1
select CHAR(RAND()*24+65) + CHAR(RAND()*24+65) + 
right('0'+CAST(CAST(RAND()*100 as int) as varchar(2)),2) + 
CHAR(RAND()*24+65) + CHAR(RAND()*24+65) 

您可能希望把種子值的RAND功能,根據您的需要做到這一點使用相同的技術或者是不可能的,謝謝。

我想真正得到這些10000 ...

select top 10000 CHAR(RAND()*24+65) + CHAR(RAND()*24+65) + 
right('0'+CAST(CAST(RAND()*100 as int) as varchar(2)),2) + 
CHAR(RAND()*24+65) + CHAR(RAND()*24+65) 
from sys.all_objects a cross join sys.all_objects b 
+0

這個返回10000行的同一序列 - 謝謝您的幫助 – Paul