天天看点

SQL Server生成随机日期模拟测试数据的需求

最近碰到个SQL Server跑SQL的性能问题,同样是关系型数据库,因此在原理层面,不同数据库之间有些内容是可以借鉴的,但是SQL Server一些细节上和操作层面,略有不同,需要熟悉和积累。

为了模拟,要插入一些测试数据,特别地需要一个存储日期(要求的格式:yyyymmdd)的字符串类型字段。我用的如下操作方式,可能有些绕,如果各位朋友有更好的方案,可以提出来,一起学习下。

1. 创建一张测试表

create table t1(id int identity(1,1) primary key, c1 varchar(10));           

复制

2. 插入10000条测试数据

insert into t1 default values
go 10000           

复制

两点要注意,

(1) go语法在DBeaver提示错误,可以在SQL Server Management Studio中执行。

(2) "go 10000"不能带";"。

此时t1中id字段由于设置了idntitiy,会得到从1到10000的值,但是c1字段为空,由于测试需求,需要让c1字段存储"yyyymmdd"的日期数值。

3. 生成随机日期的数据中间表

SQL Server生成随机数可以用函数rand(),例如,

select cast(rand()*1000 as int);           

复制

如果生成随机的日期,找了一种方式,

declare @bdate date, @edate date
set @bdate = '20210101'
set @edate = '20210601'
select id, random_date = convert(varchar(10), dateadd(day, abs(checksum(newid())))%datediff(day, @bdate, @edate), @bdate), 112)
into t2 from t1;           

复制

其中几个知识点,

(1) @bdate和@edate是生成随机日期的上下限。

(2) dateidff函数用来获取日期/时间差,入参是三个,(datepart, startdate, enddate),其中datepart表示返回两个指定日期(startdate和enddate)之间所跨的日期或时间边界的数目,此处用的day,是按照天,还可以改成second按照秒计算等。

(3) checksum()函数返回按照表的某一行或一组表达式计算出来的校验和值,他可以将文本改为一串数字。

(4) newid()返回一个新的GUID号码,永远不会重复,而且毫无规律。

(5) dateadd函数顾名思义,将一个时间间隔和指定date的指定datepart相加,返回一个新的datetime值,入参是三个,(datepart, number, date)。

(6) convert函数,这个有点意思,返回各种格式的日期字符串,如下所示,我们要的是"yyyymmdd",因此值是112,

Select CONVERT(varchar(100), GETDATE(), 0): 05 16 2006 10:57AM
Select CONVERT(varchar(100), GETDATE(), 1): 05/16/06
Select CONVERT(varchar(100), GETDATE(), 2): 06.05.16
Select CONVERT(varchar(100), GETDATE(), 3): 16/05/06
Select CONVERT(varchar(100), GETDATE(), 4): 16.05.06
Select CONVERT(varchar(100), GETDATE(), 5): 16-05-06
Select CONVERT(varchar(100), GETDATE(), 6): 16 05 06
Select CONVERT(varchar(100), GETDATE(), 7): 05 16, 06
Select CONVERT(varchar(100), GETDATE(),: 10:57:46
Select CONVERT(varchar(100), GETDATE(), 9): 05 16 2006 10:57:46:827AM
Select CONVERT(varchar(100), GETDATE(), 10): 05-16-06
Select CONVERT(varchar(100), GETDATE(), 11): 06/05/16
Select CONVERT(varchar(100), GETDATE(), 12): 060516
Select CONVERT(varchar(100), GETDATE(), 13): 16 05 2006 10:57:46:937
Select CONVERT(varchar(100), GETDATE(), 14): 10:57:46:967
Select CONVERT(varchar(100), GETDATE(), 20): 2006-05-16 10:57:47
Select CONVERT(varchar(100), GETDATE(), 21): 2006-05-16 10:57:47.157
Select CONVERT(varchar(100), GETDATE(), 22): 05/16/06 10:57:47 AM
Select CONVERT(varchar(100), GETDATE(), 23): 2006-05-16
Select CONVERT(varchar(100), GETDATE(), 24): 10:57:47
Select CONVERT(varchar(100), GETDATE(), 25): 2006-05-16 10:57:47.250
Select CONVERT(varchar(100), GETDATE(), 100): 05 16 2006 10:57AM
Select CONVERT(varchar(100), GETDATE(), 101): 05/16/2006
Select CONVERT(varchar(100), GETDATE(), 102): 2006.05.16
Select CONVERT(varchar(100), GETDATE(), 103): 16/05/2006
Select CONVERT(varchar(100), GETDATE(), 104): 16.05.2006
Select CONVERT(varchar(100), GETDATE(), 105): 16-05-2006
Select CONVERT(varchar(100), GETDATE(), 106): 16 05 2006
Select CONVERT(varchar(100), GETDATE(), 107): 05 16, 2006
Select CONVERT(varchar(100), GETDATE(), 108): 10:57:49
Select CONVERT(varchar(100), GETDATE(), 109): 05 16 2006 10:57:49:437AM
Select CONVERT(varchar(100), GETDATE(), 110): 05-16-2006
Select CONVERT(varchar(100), GETDATE(), 111): 2006/05/16
Select CONVERT(varchar(100), GETDATE(), 112): 20060516
Select CONVERT(varchar(100), GETDATE(), 113): 16 05 2006 10:57:49:513
Select CONVERT(varchar(100), GETDATE(), 114): 10:57:49:547
Select CONVERT(varchar(100), GETDATE(), 120): 2006-05-16 10:57:49
Select CONVERT(varchar(100), GETDATE(), 121): 2006-05-16 10:57:49.700
Select CONVERT(varchar(100), GETDATE(), 126): 2006-05-16T10:57:49.827:
Select CONVERT(varchar(100), GETDATE(), 131): 18/04/1427 10:57:49:920AM           

复制

通过以上函数,就可生成一个随机的日期字符串,"select ... into t2 from t1"则从t1表取出所有的记录(10000条),包括了自增的主键字段id,以及每行随机生成的日期字符串c1,插入到t2,字段名称是id和random_date。

4. 关联更新t1

其实到第三步,t2表的记录已经包含了数值字段id以及随机日期字符串字段c1,满足测试要求了,如果非得用t1,可以再更新下,关联t2,更新t1,

update t1 set t1 = t2.random_date
  from t1, t2
 where t1.id = t2.id;           

复制

其实很多函数,从名称上,在各种开发语言和数据库中都见过,因此很多技术上的知识都是相通的,做到举一反三、融会贯通,才可以慢慢提高自己的水平。