SQL Server时间粒度类别----第1节旬、月时间粒度详

2019-09-20 06:10 来源:未知

本文目录列表:

 

 

 

自定义分割月功能函数包括两个标量函数:ufn_SegMonths和ufn_SegMonth2Date。ufn_SegMonths获取指定的日期在自定义分割月对应的分割月数值;ufn_SegMonth2Date获取指定一个分割月数值赌对应的月份日期。

    执行后的查询结果如下图:

4、总结语

彩民之家高手论坛 1

我仔细梳理了这个函数进行了重构简化以及扩展,该自定义分割月函数的实现区别之前写的SQL Server时间粒度系列----第3节旬、月时间粒度详解文章中将一个整数值和月份日期相互转换功能,这个是按照标准月来实现的,虽然思路大致相同,但是并没有针对之前的月份日期和整数值转换函数对来进行扩展而是独立开发新的功能函数。也是为了尽量做到函数功能职责单一性、稳定性、可维护性以及可扩展性。

    测试以上4个函数效果的T-SQL代码如下:

2、sql server实现自定义分割月功能

1 DECLARE @dtmDate AS DATETIME;
2 SET @dtmDate = '2016-01-08';
3  
4 SELECT dbo.ufn_PeriodOfMonth(@dtmDate) AS 'Period IndexID Of Current Month(1:上旬,2:中旬,3:下旬)'
5     ,dbo.ufn_DayOfPeriod(@dtmDate) AS 'Day IndexID Of Current Period(从1开始结束,包括1、2、3、……、10、11)';
6  
7 SELECT dbo.ufn_Periods('1900-02-01') AS 'The Total Of Periods Base-on BaseDate"1900-01-01" '
8     ,dbo.ufn_Periods2Date(1) AS 'Period Basedate Mapping 100'
9 GO

3、测试验证效果

本文目录列表:

今天梳理一个平台的所有函数时,发现了一个自定义分割月函数,也就是指定分割月的开始日索引值(可以从1-31闭区间内的任何一个值)来获取指定日期所对应的分割月数值。这个函数当时是为了解决业务部门获取非标准月(标准月就是从每个月的第一天到最后一天组成一个完成的标准月份)的统计汇总数据的。例如:如果指定分割月的开始日索引值为5则表示某个月的5号到下个月的4号之间作为一个完整的分割月;同样地如果指定分割月的开始日索引值为1则表示标准月等等。

 

1、为何出现自定义分割月需求

    

 

 1 IF OBJECT_ID(N'dbo.ufn_DayOfPeriod', 'FN') IS NOT NULL
 2 BEGIN
 3     DROP FUNCTION dbo.ufn_DayOfPeriod;
 4 END
 5 GO
 6  
 7 --==================================
 8 -- 功能: 获得指定日期时间在当前旬的日索引
 9 -- 说明: 从1开始计数,包括1、2、3、……、8、9、10、11
10 -- 作者: XXX
11 -- 创建: yyyy-MM-dd
12 -- 修改: yyyy-MM-dd XXX 修改内容描述
13 -- 调用: SET @intPeriods = dbo.ufn_DayOfPeriod('2008-01-14')
14 --==================================
15 CREATE FUNCTION [dbo].[ufn_DayOfPeriod]
16 (
17     @dtmDate DATETIME            -- 指定的日期时间
18 ) RETURNS TINYINT
19     --$Encode$--
20 AS
21 BEGIN
22     RETURN DAY(@dtmDate) - (dbo.ufn_PeriodOfMonth(@dtmDate) - 1) * 10;
23 END
24 GO

继续精进SQL Server,继续进发。

彩民之家高手论坛 2彩民之家高手论坛 3

 

    执行后的查询结果如下图:

 

 

这次是梳理平台的功能性函数所进行的重构简化以及扩展的实现。尽量将日期有关的功能函数梳理出来,便于直接在sql server用户数据库中来使用, 也便于BI仓库中使用。国庆一来已经过去一周,原来打算一周一遍的计划还是延期啦,再次严重检讨自己。

 

 

    提供旬基准日期和整数相互转换的功能函数,T-SQL代码如下:

  • SQL Server数字辅助表的实现

  • SQL Server时间粒度系列----第3节旬、月时间粒度详解 

彩民之家高手论坛 4

 

彩民之家高手论坛 5

3、测试验证效果

彩民之家高手论坛 6彩民之家高手论坛 7

针对以上简单的测试代码如下:

彩民之家高手论坛 8彩民之家高手论坛 9

 

5、参考清单列表

 

彩民之家高手论坛 10

 

彩民之家高手论坛 11彩民之家高手论坛 12

IF OBJECT_ID(N'[dbo].[ufn_SegMonths]', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION [dbo].[ufn_SegMonths];
END
GO

--==================================
-- 功能:根据自定义月开始索引值获取指定日期所在的自定义月数。
-- 说明:自定义分割月数 = 年整数值*100   当前所在分割月值。
-- 环境:SQL Server 2005 。
-- 调用:SET @intSegMonths = dbo.fn_SegMonths('2008-01-14', 15)。
-- 创建:XXXX-XX-XX XX:XX-XX:XX XXX 创建函数实现。 
-- 修改:XXXX-XX-XX XX:XX-XX:XX XXX XXXXXXXX。
--==================================
CREATE FUNCTION [dbo].[ufn_SegMonths]
(
     @dtmDate AS DATETIME                        -- 日期
    ,@tntSegStartIndexOfMonth AS INT = 15        -- 自定义分割月开始索引值(1-31)
)
RETURNS INT
AS
BEGIN    
    IF (@tntSegStartIndexOfMonth = 0 OR @tntSegStartIndexOfMonth >= 32)
    BEGIN
        SET @tntSegStartIndexOfMonth = 15;
    END

    DECLARE 
         @intYears AS INT
        ,@tntMonth AS TINYINT
        ,@sntDay AS SMALLINT;        
    SELECT 
         @intYears = DATEDIFF(YEAR, '1900-01-01', @dtmDate)
        ,@tntMonth = DATEPART(MONTH, @dtmDate)
        ,@sntDay = DATEPART(DAY, @dtmDate);

    IF (@sntDay >= @tntSegStartIndexOfMonth)
    BEGIN
        SET @tntMonth = @tntMonth   1;    
    END

    IF (@tntMonth > 12)
    BEGIN
        SELECT
             @intYears = @intYears   1
            ,@tntMonth = @tntMonth - 12;
    END

    RETURN @intYears * 100   @tntMonth;
END
GO

IF OBJECT_ID(N'[dbo].[ufn_SegMonths2Date]', 'FN') IS NOT NULL
BEGIN
    DROP FUNCTION [dbo].[ufn_SegMonths2Date];
END
GO

--==================================
-- 功能:获取自定义分割月数对应的自定义分割月日期。
-- 说明:自定义分割月日期 = 自定义分割月数/100对应的年整数日期“组合”当前所在分割月值。
-- 环境:SQL Server 2005 。
-- 调用:SET @dtmSegMonthDate = dbo.fn_SegMonths2Date(11602)。
-- 创建:XXXX-XX-XX XX:XX-XX:XX XXX 创建函数实现。 
-- 修改:XXXX-XX-XX XX:XX-XX:XX XXX XXXXXXXX。;
--==================================
CREATE FUNCTION [dbo].[ufn_SegMonths2Date]
(
     @intSegMonths AS INT                        -- 自定义分割月数
)
RETURNS DATETIME
AS
BEGIN        
    DECLARE @dtmDefaultBasedate AS DATETIME;
    SET @dtmDefaultBasedate = '1900-01-01';

    IF ((@intSegMonths IS NULL) OR (@intSegMonths <= 0))
    BEGIN
        RETURN @dtmDefaultBasedate;
    END

    DECLARE 
         @intYears AS INT
        ,@intMonth AS INT;    
    SELECT 
         @intYears = @intSegMonths / 100
        ,@intMonth = @intSegMonths % 100;    

    RETURN DATEADD(MONTH, @intMonth - 1, DATEADD(YEAR, @intYears, @dtmDefaultBasedate));
END
GO

1、

5、参考清单列表

    测试有关月时间粒度的函数效果的T-SQL代码如下:

1、为何出现自定义分割月的需求

3、SQL Server函数重构

DECLARE 
     @dtmStartDate AS DATETIME
    ,@dtmEndDate AS DATETIME;

SELECT
     @dtmStartDate = '2000-01-01'
    ,@dtmEndDate = '2016-12-31';

SELECT 
    [T1].*
    ,[dbo].[ufn_SegMonths2Date]([T1].[SegMonths]) AS SegMonthDate
FROM (
    SELECT 
        [T].[CDate]
        ,[dbo].[ufn_SegMonths]([T].[CDate], 28) AS SegMonths

    FROM (
        SELECT 
            DATEADD(DAY, [Num], @dtmStartDate) AS CDate
        FROM 
            [dbo].[ufn_GetNums](0, DATEDIFF(DAY, @dtmStartDate, @dtmEndDate))
    ) AS T
    WHERE [T].[CDate] BETWEEN '2014-12-01' AND '2016-03-31'
) AS T1
WHERE DATEPART(DAY, [T1].[CDate]) >= 27
GO

    在旬时间粒度小节中,我们引入了旬基准日期的概念,针对月基准日期的定义就是每月的第一天代表的日期时间值,比如”2016-01-08“所在的月基准日期就是”2016-01-01“。我们也提供月基准日期和整数相互转换的功能函数。指定日期的月份在当前季度中的月索引,从1开始计数,包括1、2、3。SQL Server提供了month(@dtmDateTime)或datepart(month, @dtmDateTime)获取指定日期所在月份(当前年的份索引,从1开始计数,包括1,、2、3、……、10、11、12)。

5、参考清单列表

View Code

彩民之家高手论坛 13

    

效果截图如下:

1 SELECT dbo.ufn_GetValidDate(NULL) AS 'NULL Default BaseDate"1900-01-01"', dbo.ufn_GetValidDate('1899-12-31') AS 'Less Than BaseDate"1900-01-01" Default BaseDate"1900-01-01"', dbo.ufn_GetValidDate('2016-01-08') AS '2016-01-08'
2 SELECT dbo.ufn_GetValidDateNum(NULL) AS 'NULL Defult 0', dbo.ufn_GetValidDateNum(-1) AS 'Less Than 0 Defult 0', dbo.ufn_GetValidDateNum(12) AS '12'
3 GO

彩民之家高手论坛 14

    提供以上功能函数的重构,T-SQL代码如下:

 

    提供获得指定日期在当前旬第几天的功能函数,T-SQL代码如下:

 

 1 DECLARE @dtmDate AS DATETIME;
 2 SET @dtmDate = '';
 3  
 4 SELECT @dtmDate AS '"" Default BaseDate"1900-01-01"';
 5 SET @dtmDate = 0;
 6 SELECT @dtmDate AS '0 Default BaseDate"1900-01-01"';
 7 SET @dtmDate = @dtmDate   1;
 8 SELECT @dtmDate AS 'Add operator 等同dateadd(day, num, date)';
 9 SET @dtmDate  = -1;
10 SELECT @dtmDate AS 'substract operator 等同dateadd(day, -1*num, date)';
11 GO

 

总结语

4、总结语

View Code

注意:以上测试代码使用了SQL Server数字辅助表的实现这边文章的内联表值函数ufn_GetNums。

    

2、sql server实现自定义分割月功能

参考清单列表

 

 

sql server 版本的实现T-SQL代码如下:

SQL Server函数重构

彩民之家高手论坛 15彩民之家高手论坛 16

彩民之家高手论坛 17彩民之家高手论坛 18

View Code

View Code

View Code

 1 IF OBJECT_ID(N'dbo.ufn_Months', 'FN') IS NOT NULL
 2 BEGIN
 3     DROP FUNCTION dbo.ufn_Months;
 4 END
 5 GO
 6  
 7 --==================================
 8 -- 功能: 获得指定日期时间基于基准日期的总月数(一个整数值)
 9 -- 说明: 如果指定的日期时间为NULL或者小于基准日期“1900-01-01”时,则其值默认基准日期
10 --       结果值为非负整数,从0开始计数。
11 -- 作者: XXX
12 -- 创建: yyyy-MM-dd
13 -- 修改: yyyy-MM-dd XXX 修改内容描述
14 -- 调用: SET @intMonths = dbo.ufn_Months('2008-01-14')
15 --==================================
16 CREATE FUNCTION dbo.ufn_Months 
17 (
18     @dtmDate DATETIME
19 ) RETURNS INT
20 AS
21 BEGIN
22     IF @dtmDate IS NULL OR @dtmDate < '1900-01-01'
23     BEGIN
24         SET @dtmDate = '1900-01-01';
25     END
26  
27     -- datepart参数也可以为mm或m
28     RETURN DATEDIFF(MONTH, '1900-01-01', @dtmDate);
29 END
30 GO
31  
32 IF OBJECT_ID(N'dbo.ufn_Months2Date', 'FN') IS NOT NULL
33 BEGIN
34     DROP FUNCTION dbo.ufn_Months2Date;
35 END
36 GO
37  
38 --==================================
39 -- 功能: 获得一个整数值基于基准日期对应的月基准日期
40 -- 说明: 如果指定的整数值为NULL或为负整数时,则其值默认为0;
41 --       如果指定的整数值大于“9999-12-31”对应的整数值时,则其值默认设置为“9999-12-31”对应的整数值;
42 --       结果值为从基准日期开始计数的日期;
43 --       月基准日期是指一个月份中第1天对应的日期,比如'2016-02'月份的月旬基准日期为'2016-02-01'。
44 -- 作者: XXX
45 -- 创建: yyyy-MM-dd
46 -- 修改: yyyy-MM-dd XXX 修改内容描述
47 -- 调用: SET @dtmDate = dbo.ufn_Months2Date(1296) --'2008-01-01'
48 --==================================
49 CREATE FUNCTION dbo.ufn_Months2Date 
50 (
51     @intMonths INT
52 ) RETURNS DATETIME
53 AS
54 BEGIN
55     IF @intMonths IS NULL OR @intMonths < 0
56     BEGIN
57         SET @intMonths = 0;
58     END
59  
60     DECLARE @intMaxMonths AS INT;
61     SET @intMaxMonths = dbo.ufn_Months('9999-12-31');
62  
63     IF @intMonths >= @intMaxMonths
64     BEGIN
65         SET @intMonths = @intMaxMonths;
66     END
67  
68     -- datepart参数也可以为mm或m
69     RETURN DATEADD(MONTH, @intMonths, '1900-01-01');
70 END
71 GO

 

View Code

彩民之家高手论坛 19彩民之家高手论坛 20

    执行后的查询结果如下图:

 

1、SQL Server旬时间粒度
2、SQL Server月有关时间粒度

4、总结语

     提供获得指定日期在当前月哪个旬的功能的函数,T-SQL代码如下:

 

 

    测试以上功能函数的T-SQL代码如下:

 1 IF OBJECT_ID(N'dbo.ufn_MonthOfQuarter', N'FN') IS NOT NULL
 2 BEGIN
 3     DROP FUNCTION dbo.ufn_MonthOfQuarter;
 4 END
 5 GO
 6  
 7 --==================================
 8 -- 功能: 获得一个日期时间的月份在当前季度的月索引
 9 -- 说明: 如果指定的整数值为NULL时,则其值默认设置为基准日期'1900-01-01';
10 --       结果值从1开始计数,包括1、2、3。
11 -- 作者: XXX
12 -- 创建: yyyy-MM-dd
13 -- 修改: yyyy-MM-dd XXX 修改内容描述
14 -- 调用: SET @dtmDate = dbo.ufn_MonthOfQuarter(2008-01-01);
15 --==================================
16 CREATE FUNCTION dbo.ufn_MonthOfQuarter
17 (
18     @dtmDate DATETIME            -- 指定的日期时间
19 ) RETURNS TINYINT
20 AS
21 BEGIN
22     SET @dtmDate = ISNULL(@dtmDate, '1900-01-01');
23     DECLARE @tintMonthOfQuarter AS TINYINT;
24     SET @tintMonthOfQuarter = 0;
25  
26     DECLARE @tintMonthOfYear AS TINYINT;
27     SET @tintMonthOfYear = MONTH(@dtmDate);
28  
29     SET @tintMonthOfQuarter =  @tintMonthOfYear - @tintMonthOfYear / 3 * 3;
30  
31     IF @tintMonthOfQuarter = 0
32     BEGIN
33         SET @tintMonthOfQuarter = 3;
34     END
35  
36     RETURN @tintMonthOfQuarter;
37 END
38 GO
39  

    

    执行后的查询结果如下图:

 

    

1 DECLARE @dtmDate AS DATETIME;
2 SET @dtmDate = '2016-01-08';
3  
4 SELECT dbo.ufn_MonthOfQuarter(@dtmDate) AS 'Month IndexID Of Current Quarter(1:第1个月,2:第2个月,3:第3个月)'
5     ,MONTH(@dtmDate) AS 'Month IndexID Of Current Year', DATEPART(MONTH, @dtmDate) AS 'Month IndexID Of Current Year(从1开始结束,包括1、2、3、……、10、12))';
6  
7 SELECT dbo.ufn_Months(@dtmDate) AS 'The Total Of Months Base-on BaseDate"1900-01-01"'
8     ,dbo.ufn_Months2Date(2) AS 'Month Basedate Mapping 2';
9 GO

 

SQL Server旬时间粒度

 1 IF OBJECT_ID(N'dbo.ufn_Periods', 'FN') IS NOT NULL
 2 BEGIN
 3     DROP FUNCTION dbo.ufn_Periods;
 4 END
 5 GO
 6  
 7 --==================================
 8 -- 功能: 获得指定日期时间基于基准日期的总旬数(一个整数值)
 9 -- 说明: 如果指定的日期时间为NULL或者小于基准日期“1900-01-01”时,则其值默认基准日期;
10 --       结果值为非负整数,从0开始计数。
11 -- 作者: XXX
12 -- 创建: yyyy-MM-dd
13 -- 修改: yyyy-MM-dd XXX 修改内容描述
14 -- 调用: SET @intPeriods = dbo.ufn_Periods('2008-01-14')
15 --==================================
16 CREATE FUNCTION [dbo].[ufn_Periods] 
17 (
18     @dtmDate DATETIME            -- 指定的日期时间
19 ) RETURNS INT
20     --$Encode$--
21 AS
22 BEGIN
23     SET @dtmDate = dbo.ufn_GetValidDate(@dtmDate);
24  
25     -- 旬偏移索引ID,0:上旬,1:中旬,2:下旬
26     DECLARE @tintPeriodOffsetIndexID AS INT;
27     SET @tintPeriodOffsetIndexID = dbo.ufn_PeriodOfMonth(@dtmDate);
28  
29     -- datepart参数也可以为mm或m
30     RETURN DATEDIFF(MONTH, '1900-01-01', @dtmDate) * 3   @tintPeriodOffsetIndexID;
31 END
32 GO
33  
34 IF OBJECT_ID(N'dbo.ufn_Periods2Date', 'FN') IS NOT NULL
35 BEGIN
36     DROP FUNCTION dbo.ufn_Periods2Date;
37 END
38 GO
39  
40 --==================================
41 -- 功能: 获得一个整数值基于基准日期对应的旬基准日期
42 -- 说明: 如果指定的整数值为NULL或为负整数时,则其值默认为0;
43 --       如果指定的整数值大于“9999-12-31”对应的整数值时,则其值默认设置为“9999-12-31”对应的整数值;
44 --       结果值为从基准日期开始计数的日期;
45 --       旬基准日期是指一个月份中第1天、第11天和第21天对应的日期,比如'2016-02'月份的3个旬基准日期分别为'2016-02-01','2016-02-11','2016-02-21'。
46 -- 作者: XXX
47 -- 创建: yyyy-MM-dd
48 -- 修改: yyyy-MM-dd XXX 修改内容描述
49 -- 调用: SET @dtmDate = dbo.ufn_Periods2Date(2705) --'1975-02-21'
50 --==================================
51 Create FUNCTION dbo.ufn_Periods2Date 
52 (
53     @intPeriods INT
54 ) RETURNS DATETIME
55 AS
56 BEGIN
57     SET @intPeriods = dbo.ufn_GetValidDateNum(@intPeriods);
58  
59     DECLARE @intMaxPeriods AS INT;
60     SET @intMaxPeriods = dbo.ufn_Periods('9999-12-31');
61  
62     IF @intPeriods >= @intMaxPeriods
63     BEGIN
64         SET @intPeriods = @intMaxPeriods;
65     END
66  
67     -- datepart参数也可以为mm或m
68     -- 以下注释的也可以,不过更接近相对日期 偏移数得到旬基准日期。
69     --RETURN DATEADD(MONTH, @intPeriods / 3, '1900-01-01')   (@intPeriods - @intPeriods / 3 * 3) * 10;
70     RETURN DATEADD(DAY,  (@intPeriods - @intPeriods / 3 * 3) * 10, DATEADD(MONTH, @intPeriods / 3, '1900-01-01'));
71 END
72 GO

    提供月基准日期和整数相互转换的功能函数,T-SQL代码入下:

 

 1 IF OBJECT_ID(N'dbo.ufn_PeriodOfMonth', 'FN') IS NOT NULL
 2 BEGIN
 3     DROP FUNCTION dbo.ufn_PeriodOfMonth;
 4 END
 5 GO
 6  
 7 --==================================
 8 -- 功能: 获得指定日期时间在当前月的旬索引
 9 -- 说明: 从1开始计数,1、2、3分别对应上、中、下的旬索引。
10 -- 作者: XXX
11 -- 创建: yyyy-MM-dd
12 -- 修改: yyyy-MM-dd XXX 修改内容描述
13 -- 调用: SET @intPeriods = dbo.ufn_PeriodOfMonth('2008-01-14')
14 --==================================
15 CREATE FUNCTION [dbo].[ufn_PeriodOfMonth] 
16 (
17     @dtmDate DATETIME            -- 指定的日期时间
18 ) RETURNS TINYINT
19     --$Encode$--
20 AS
21 BEGIN
22     --当前月的日索引,从1开始计数,,包括1、2、3、……、28、29、30、31
23     DECLARE @tintDayOfMonth AS TINYINT;
24     SET @tintDayOfMonth = DAY(@dtmDate);
25     -- 旬偏移索引,0:上旬,1:中旬,2:下旬
26     DECLARE @tintPeriodOffsetIndexID AS INT;
27     SET @tintPeriodOffsetIndexID = DAY(@dtmDate) / 10
28  
29     IF @tintDayOfMonth IN (10, 20, 30, 31)
30     BEGIN
31         SET @tintPeriodOffsetIndexID = @tintPeriodOffsetIndexID - 1;
32     END
33  
34     RETURN @tintPeriodOffsetIndexID   1;
35 END
36 GO

 彩民之家高手论坛 21

View Code

彩民之家高手论坛 22

注意:以上的测试代码,SQL Server引擎默认使用了基准日期”1900-01-01“。

彩民之家高手论坛 23彩民之家高手论坛 24

    SQL Server不存在旬这个时间粒度,这个时间粒度在我们国家存在的。一个月分为上、中、下3旬,上旬和中旬均10天,分别对应第1天到第10天和第11天到第20天,下旬有可能8天、9天、10天和11天,从第21天到月末最后1天。从旬的定义得知旬是个日期时间范围的,那么如何实现将旬时间粒度时间值和一个对应的整数来实现相互转换呢?从旬的定义得知每旬都有个开始日期的,这个日期我们就叫做旬基准日期。如果同一旬的任意一个日期都对应一个相同的整数,那么再将一个整数转换为一个旬基准日期,这样我们可以实现旬基准日期和整数的相互转换。我们还可以得到每个日期在所在旬的第几天,也可以将得到一个月份每日期所在的旬索引(这个类似每周的任何一天对应的weekday值,从1到7分别对应星期一到星期日)。

 

注意:重复的代码实现了重构,本文中提供的重复代码所在的函数没有做变更的,需要的话请自己调整和修改代码。

彩民之家高手论坛 25

    测试日期时间与加减运算符的效果,T-SQL代码如下:

    本文在SQL Server时间粒度详解小节中,提供了获取指定日期所在旬的日索引功能和获取指定日期的所在旬在当前月的旬索引,以及旬基准日期和整数相互转换的功能函数。还实现了月基准日期和整数相互转换的功能函数,获取指定日期的月份在当前季度的月索引功能。还提供了T-SQL代码重构的例子,通过封装通用的功能函数来消除重复的T-SQL代码。也提供了日期时间数据类型的变量与加减运算符的测试代码,主要印证SQL Server引擎默认也是在使用基准日期”1900-01-01“。

View Code

 

    提供获得指定日期的月份在当前季度的月索引,T_SQL代码如下:

彩民之家高手论坛 26彩民之家高手论坛 27

   在旬和月时间粒度已经提供的功能函数,我们会针对指定的日期时间和整数参数做进行相应的条件处理,发现了很多的重复T-SQL代码,为消除相似功能的重复代码,我将其封装在以下两个功能函数ufn_GetVlidDate和ufn_GetValidDateNum,分别提供对指定的日期时间和指定的日期数的有效性处理。

 彩民之家高手论坛 28

View Code

 

 

 

彩民之家高手论坛 29彩民之家高手论坛 30

View Code

2、

SQL Server月有关时间粒度

 1 IF OBJECT_ID(N'dbo.ufn_GetValidDate', 'FN') IS NOT NULL
 2 BEGIN
 3     DROP FUNCTION dbo.ufn_GetValidDate;
 4 END
 5 GO
 6  
 7 --==================================
 8 -- 功能: 获取有效日期
 9 -- 说明: 指定的日期如果为NULL或者小于基准日期'1900-01-01'则默认设置为基准日期'1900-00-01'
10 -- 作者: XXX
11 -- 创建: yyyy-MM-dd
12 -- 修改: yyyy-MM-dd XXX 修改内容描述
13 -- 调用: SET @dtmDate = dbo.ufn_GetValidDate('2008-01-14')
14 --==================================
15 CREATE FUNCTION dbo.ufn_GetValidDate
16 (
17     @dtmDate DATETIME            -- 指定的日期数
18 ) RETURNS DATETIME
19     --$Encode$--
20 BEGIN
21     IF @dtmDate IS NULL OR @dtmDate < '1900-01-01'
22     BEGIN
23         RETURN '1900-01-01';
24     END
25  
26     RETURN @dtmDate;
27 END
28 GO
29  
30 IF OBJECT_ID(N'dbo.ufn_GetValidDateNum', 'FN') IS NOT NULL
31 BEGIN
32     DROP FUNCTION dbo.ufn_GetValidDateNum;
33 END
34 GO
35  
36 --==================================
37 -- 功能: 获取有效日期数
38 -- 说明: 指定的日期数如果为NULL或负数,则默认设置为0
39 -- 作者: XXX
40 -- 创建: yyyy-MM-dd
41 -- 修改: yyyy-MM-dd XXX 修改内容描述
42 -- 调用: SET @@intDateNum = dbo.ufn_GetValidDateNum(-1)
43 --==================================
44 CREATE FUNCTION dbo.ufn_GetValidDateNum
45 (
46     @intDateNum INT            -- 指定的日期数
47 ) RETURNS INT
48     --$Encode$--
49 BEGIN
50     IF @intDateNum IS NULL OR @intDateNum < 0
51     BEGIN
52         RETURN 0;
53     END
54  
55     RETURN @intDateNum;
56 END
57 GO
版权声明:本文由彩民之家高手论坛发布于彩民之家高手论坛,转载请注明出处:SQL Server时间粒度类别----第1节旬、月时间粒度详