类别:数据库
日期:2021-01-25 浏览:2168 评论:0
CHECKSUM ( * | expression [ ,...n ] ) 此函数生成按照表的某一行或一组表达式计算出来的int校验和值,CHECKSUM 用于生成哈希索引(详细说明查看https://technet.microsoft.com/zh-cn/library/ms189788(v=sql.90).aspx)。
从上面的查询结果看到组合生成的整数数值都是9位数的,平时工作中大多使用的随机整数值都是不太大的且都是自然数(0和正整数的集合),这就要求限制随机生成的整数数值。可以使用函数ABS对其结果进行处理得到任意一个自然数。这样,组合一起来的格式就是这样的:ABS(CHECKSUM(NEWID()))。为了便于使用便于使用我们通过将其封装到函数中,但是函数NEWID又不能在函数中使用,那我们就要考虑其他的方式:将函数NEWID封装在单列单行的视图中。其定义视图的T-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
执行后的查询结果如下:
针对以上的分析我们封装的T-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
SELECT dbo.ufn_RandNum(0, 1) AS RandNum, dbo.ufn_RandNum(10, 13) AS RandNum2 from dbo.HIS_Item
那么我们继续讲解 获取指定区间内的任意一个随机日期,不过我们要使用日期和时间的两个函数:DATEADD和DATEDIFF。使用DATEDIFF计算出日期区间的间隔值,同上的思路我们计算得到的一个随机整数值,然后通过DATEADD得到我们期望的一个随机日期。封装函数的T-SQL代码如下:
IF OBJECT_ID(N'dbo.ufn_RandDate', 'FN') IS NOT NULL BEGIN DROP FUNCTION dbo.ufn_RandDate; END GO --================================== -- 功能: 获取日期区间内的任意一个随机日期 -- 说明: 具体实现阐述 -- 作者: XXX -- 创建: yyyy-MM-dd -- 修改: yyyy-MM-dd XXX 修改内容描述 -- 调用: SELECT @dtmRand = dbo.ufn_RandDate('2007-02-01', '2007-03-01'); --================================== CREATE FUNCTION dbo.ufn_RandDate ( @dtmMin DATETIME, -- 随机日期的最小值 @dtmMax DATETIME -- 随机日期的最大值 ) RETURNS DATETIME --$Encode$-- AS BEGIN SET @dtmMin = ISNULL(@dtmMin, '2000-01-01'); SET @dtmMax = ISNULL(@dtmMax, '2000-01-01'); DECLARE @guidVue AS UNIQUEIDENTIFIER; SELECT TOP 1 @guidVue = RandomGuid FROM dbo.vRandomGuid; -- 可以将HOUR换为DAYS RETURN DATEADD(HOUR, (ABS(CHECKSUM(@guidVue)) % (1 + DATEDIFF(HOUR, @dtmMax, @dtmMin))), @dtmMin); END GO
调用以上函数的T-SQL代码如下:
SELECT dbo.ufn_RandDate('2015-12-01', '2015-12-21') AS RandDate, dbo.ufn_RandDate('2016-12-01', '2016-12-21') AS RandDate2; GO
1 SELECT TOP 1 Num 2 FROM dbo.SeqDataTable 3 WHERE Num BETWEEN @intMin AND @intMax 4 ORDER BY NEWID() ASC; 5 GO
当然也可以利用以上的数字序列SeqDataTable(Num INT),日期区间[@dtmMin,@dtmMax],那个该数字区间任意一个随机日期的T-SQL代码如下:
1 SELECT TOP 1 DATEADD(DAY, Num, @dtmMin) 2 FROM dbo.SeqDataTable 3 WHERE Num BETWEEN 0 AND DATEDIFF(DAY, @dtmMin, @dtmMax) 4 ORDER BY NEWID() ASC; 5 GO
注意:以上代码无法执行成功的,也算是伪代码的。
获取指定范围的任意一个数字的T-SQL代码如下:
SELECT TOP 1 Num FROM dbo.ufn_GetNums(@bintMin, @bintMax) ORDER BY NEWID() ASC; GO SELECT TOP 1 Num FROM dbo.ufn_GetNums(11, 15) ORDER BY NEWID() ASC; GO
获取指定范围的任意一个日期的T-SQL代码如下:
SELECT TOP 1 DATEADD(DAY, Num, @dtmMin) FROM dbo.ufn_GetNums(0, DATEDIFF(DAY, @dtmMax, @dtmMin)) ORDER BY NEWID() ASC; GO SELECT TOP 1 DATEADD(DAY, Num, '2015-12-01') FROM dbo.ufn_GetNums(0, DATEDIFF(DAY, '2015-12-01', '2015-12-05')) ORDER BY NEWID() ASC; GO
以上代码中的表函数ufn_GetNums可以参看这篇博文SQL Server数字辅助表的实现
发表评论 / 取消回复