在資料模擬、測試資料生成或隨機抽樣等情境中,SQL Server 的隨機數函數扮演關鍵角色。本文系統整理 RAND、CHECKSUM、NEWID 三大核心函數特性,並逐步推導出高效能的「區間隨機整數」與「區間隨機日期」通用函數,供開發者直接部署應用。
| 函數 | 回傳型別 | 值域/特性 | 適用場景 |
|---|---|---|---|
RAND([seed]) | float | 0 ~ 1 之間的浮點數。指定 seed 時結果固定。 | 簡單隨機抽樣、機率計算 |
CHECKSUM(expr...) | int | 依輸入運算式計算雜湊校驗和。輸入固定則結果固定。 | 雜湊索引、快速比較資料列差異 |
NEWID() | uniqueidentifier | 全域唯一識別碼 (GUID),每次呼叫皆不同。 | 唯一鍵值、產生高熵亂數種子 |
RAND 產生浮點數,轉整數需額外運算;CHECKSUM 雖為整數但需變動輸入才能產生不同值;NEWID 唯一但非數值型別。組合策略:以 NEWID() 作為 CHECKSUM 的參數,每次呼叫即可獲得不同的 int 值:
SELECT CHECKSUM(NEWID()) AS RandomInt;
結果為 9 位數正負整數。若需自然數(含 0),包裹 ABS():
SELECT ABS(CHECKSUM(NEWID())) AS NaturalRandom;
使用者定義函數 (UDF) 內不允許呼叫 NEWID()。解法:建立單列單行的檢視表封裝 NEWID(),函數再查詢該檢視表。
-- 建立隨機 GUID 檢視表 IF OBJECT_ID(N'dbo.vRandomGuid', 'V') IS NOT NULL DROP VIEW dbo.vRandomGuid; GO CREATE VIEW dbo.vRandomGuid AS SELECT RandomGuid = NEWID(); GO -- 使用方式 SELECT TOP 1 RandomGuid FROM dbo.vRandomGuid;

ufn_RandNum利用取模運算將亂數映射至指定區間 [@intMin, @intMax]:
CREATE FUNCTION dbo.ufn_RandNum (
@intMin INT, -- 區間最小值
@intMax INT -- 區間最大值
) RETURNS INT
AS BEGIN
SET @intMin = ISNULL(@intMin, 0);
SET @intMax = ISNULL(@intMax, 2147483647);
DECLARE @guidValue UNIQUEIDENTIFIER;
SELECT TOP 1 @guidValue = RandomGuid FROM dbo.vRandomGuid;
RETURN ABS(CHECKSUM(@guidValue)) % (@intMax - @intMin + 1) + @intMin;
END;
GO
-- 呼叫範例:取得 100 ~ 200 之間的隨機整數
SELECT dbo.ufn_RandNum(100, 200) AS RandNum;

ufn_RandDate結合 DATEDIFF 計算區間總小時數(或天數),再以 DATEADD 加上隨機偏移:
CREATE FUNCTION dbo.ufn_RandDate (
@dtmMin DATETIME, -- 起始日期
@dtmMax DATETIME -- 結束日期
) RETURNS DATETIME
AS BEGIN
SET @dtmMin = ISNULL(@dtmMin, '1900-01-01');
SET @dtmMax = ISNULL(@dtmMax, '9999-12-31');
DECLARE @guidValue UNIQUEIDENTIFIER;
SELECT TOP 1 @guidValue = RandomGuid FROM dbo.vRandomGuid;
-- 以小時為單位,若需天數精度請將 HOUR 改為 DAY
RETURN DATEADD(HOUR,
ABS(CHECKSUM(@guidValue)) % (DATEDIFF(HOUR, @dtmMin, @dtmMax) + 1),
@dtmMin);
END;
GO
-- 呼叫範例:取得 2023 年全年的隨機日期時間
SELECT dbo.ufn_RandDate('2023-01-01', '2023-12-31 23:59:59') AS RandDate;

若環境已備妥連續數值表 SeqDataTable(Num INT),可結合 ORDER BY NEWID() 直接抽樣,無需自訂函數:
-- 隨機整數 SELECT TOP 1 Num FROM dbo.SeqDataTable WHERE Num BETWEEN @intMin AND @intMax ORDER BY NEWID(); -- 隨機日期 SELECT TOP 1 DATEADD(DAY, Num, @dtmMin) FROM dbo.SeqDataTable WHERE Num BETWEEN 0 AND DATEDIFF(DAY, @dtmMin, @dtmMax) ORDER BY NEWID();
註:上述為概念示範,實際部署需依資料量調整效能策略。
ABS(CHECKSUM(NEWID())) 為高熵整數亂數基石。NEWID()。value % (max-min+1) + min。掌握這些模式,即可靈活應對各類測試資料生成與隨機抽樣需求。