我有以下存储过程,但它似乎没有返回 6 个数字:
CREATE PROCEDURE GenerateRandomNumbers
(
@StartNumber tinyint,
@EndNumber tinyint,
@QuantityToOutput tinyint,
@AllowDuplicates bit --0 = No, 1 = Yes (Of Course)
)
AS
BEGIN
--Make sure that the input params are valid
--@StartNumber must be less than @EndNumber
IF @StartNumber >= @EndNumber
PRINT 'You turkey! @StartNumber has to be LESS THAN @EndNumber!'
RETURN
--@EndNumber - @StartNumber must be >= @QuantityToOutput IF @AllowDuplicates = 0
IF @AllowDuplicates = 0 AND @EndNumber - @StartNumber <= @QuantityToOutput
PRINT 'Not enough numbers in the range to satisfy your OUTPUT and DUPLICATE parameter settings!'
RETURN
--We're good to go if we get this far.
--Create a table to hold the "boundary points" of each number.
CREATE TABLE #NumberBoundaries
(Number tinyint, UpperLimit decimal (15,10) )
INSERT #NumberBoundaries(Number, UpperLimit)
SELECT sv.number,
--The line below implements the "end point" math I spoke about earlier.
(1.0000000/(@EndNumber + 1 - @StartNumber) * (sv.Number + 1 - @StartNumber)) AS UpperLimit
FROM master..spt_values sv
WHERE sv.Number <= @EndNumber AND sv.Number >= @StartNumber ANDsv.type = 'P'
--This holds the generated numbers until we have enough to return a result set
CREATE TABLE #NumbersToOutput(Number tinyint NOT NULL )
--Loop until we're dizzy
WHILE (SELECT COUNT(*) FROM #NumbersToOutput) < @QuantityToOutput
BEGIN
--This CTE fetches the bucket in which a given execution of RAND() falls.
WITH MyNumber (Number)
AS (SELECT TOP 1 nb.Number
FROM #NumberBoundaries nb
WHERE RAND() < nb.UpperLimit
ORDER BY nb.Number ASC)
INSERT #NumbersToOutput
SELECT mn.Number
FROM MyNumber mn
--The line below allows us to either permit duplicates or check for them.
WHERE @AllowDuplicates = 1
OR mn.Number NOT IN (SELECT Number FROM #NumbersToOutput)
END
--Return our numbers
SELECT Number
FROM #NumbersToOutput
ORDER BY 1
END
我使用以下调用存储过程:
EXEC GenerateRandomNumbers 1, 49, 6, 0