SQL Server中如何實現區間隨機數值函式的實現?
工作中會遇到SQL Server模擬資料生成以及數值列值(如整型、日期和時間資料型別)隨機填充等等任務,這些任務中都要使用到隨機數。鑑於此,本文將對SQL Server中隨機數的使用簡單做個總結。
T-SQL 隨機有關的三個函式
RAND([seed]此函式生成從0到1之間隨機float值(詳細說明檢視https://technet.microsoft.com/zh-cn/library/ms177610(v=sql.90).aspx)。
CHECKSUM ( * | expression [ ,...n ] )此函式生成按照表的某一行或一組表示式計算出來的int
NEWID ( )此函式生成uniqueidentifier型別的唯一值(詳細說明檢視https://technet.microsoft.com/zh-cn/library/ms190348(v=sql.90).aspx)。
生成任意一個隨機數值(如整數、日期和時間資料型別)
如果獲得任意一個隨機整數值?函式RAND生成的結果是float資料型別的,顯然很難滿足要求,不過可以通過對函式RAND的結果繼續加工(比如其結果乘以某一個值保留整數部分等等)得到要求。很顯然,函式CHECKSUM生成的結果是int資料型別,很容易滿足我們的結果,不過其引數如果固定(表的某一行值相同或一組表示式值相同),那麼其結果也是相同的。函式NEWID可以保證結果的唯一,但是其結果是unigueidentifer資料型別的。
從以上三個函式的結果值分析:函式RNAD和CHECKSUM的結果是能獲得整數數值的。如果我們將函式NEWID的結果值作為函式CHECKSUM的引數,那麼其每次生成的結果值都是不一樣的int資料型別的數值。以下T-SQL程式碼如下:
SELECTCHECKSUM(NEWID())ASCheckSumValue,CHECKSUM(NEWID())ASCheckSumValue2;
GO
執行後的查詢結果如下:
從上面的查詢結果看到組合生成的整數數值都是9位數的,平時工作中大多使用的隨機整數值都是不太大的且都是自然數(0和正整數的集合),這就要求限制隨機生成的整數數值。可以使用函式ABS對其結果進行處理得到任意一個自然數。這樣,組合一起來的格式就是這樣的:ABS(CHECKSUM(NEWID()))。為了便於使用便於使用我們通過將其封裝到函式中,但是函式NEWID又不能在函式中使用,那我們就要考慮其他的方式:將函式NEWID封裝在單列單行的檢視中。其定義檢視的T-SQL程式碼如下:
SQL
IF OBJECT_ID(N'dbo.vRandomGuid', 'V') IS NOT NULL
BEGIN
DROP VIEW dbo.vRandomGuid;
END
GO
--==================================
-- 功能: 隨機Guid檢視
-- 說明: 具體實現闡述
-- 作者: XXX
-- 建立: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改內容描述
--==================================
CREATE VIEW dbo.vRandomGuid
--$Encode$--
AS
SELECT RandomGuid = NEWID();
GO
--呼叫該檢視的T-SQL程式碼如
SELECT TOP 1 RandomGuid
FROM dbo.vRandomGuid;
GO
執行後的查詢結果如下:
生成整數區間內的任意一個隨機整數
上面的檢視定義,我們繼續講解組合函式的進一步封裝。我們先講解如何限制隨機生成的數值,取模運算可以實現生成在指定數值區間內的任意一個數值,例如:獲取區間[3,5]內任意一個數字,我們設為區間的最小值為@intMin:3,最大值為@intMax,則該區間的間隔值為 @intMax - @intMin + 1: 5 - 3 + 1(3),那麼針對任意的整數值設為為@intValue,然後對這個間隔值先進行取模運算在加上區間最小值,最後得到的值為: @intValue % (@intMax - @intMin +1) + @intMin。如果@intValue為8,則結果值為5;如果@intValue為9,則結果值為3;如果@intValue為10,則結果值為4……
針對以上的分析我們封裝的T-SQL程式碼如下:
SQL
IF OBJECT_ID(N'dbo.ufn_RandNum', 'FN') IS NOT NULL
BEGIN
DROP FUNCTION dbo.ufn_RandNum;
END
GO
--==================================
-- 功能: 獲取區間內的任意一個隨機數值
-- 說明: 具體實現闡述
-- 作者: XXX
-- 建立: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改內容描述
-- 呼叫: SELECT dbo.ufn_RandNum(0, 1);
--==================================
CREATE FUNCTION dbo.ufn_RandNum
(
@intMin INT, -- 隨機數值的最小值
@intMax INT -- 隨機數值的最大值
) RETURNS INT
--$Encode$--
AS
BEGIN
SET @intMin = ISNULL(@intMin, 0);
SET @intMax = ISNULL(@intMax, 0);
DECLARE @guidValue AS UNIQUEIDENTIFIER;
SELECT TOP 1 @guidValue = RandomGuid
FROM dbo.vRandomGuid;
RETURN ABS(CHECKSUM(@guidValue)) % (@intMax - @intMin + 1) + @intMin;
END
GO
呼叫以上函式的T-SQL程式碼如下:
SQL
SELECT dbo.ufn_RandNum(0, 1) AS RandNum, dbo.ufn_RandNum(10, 13) AS RandNum2 from dbo.HIS_Item
執行後的查詢結果如下: