在使用 SQL 服务器函数计算到期日方面需要帮助
Need assistance in calculating Due Date using SQL Server Functions
我正在尝试根据以下限制使用发票日期计算到期日
会有两个文本框,一个是输入月几,另一个是输入到期月的前一天
如果该月的第几天是 4 并且到期月份的前一天是 5 我们必须通过减去 4 和 5 来计算值,如果减去的值为 -ve 1 并且如果输入发票日期是 11/13/2016,因此截止日期必须是 12/04/2017(这里的 04 是星期几)
如果该月的第几天是 15 并且到期月份的前一天是 5 并且减去的值为 10(非负数)输入的发票日期是 11/13/2016 意味着到期日期必须为 12/15/2016(这里的 15 是月份中的第几天)如果发票日期小于或等于减去的值,即 10,如发票日期 11/09/2016,则发票日期必须为 11/15/2016
注意上述约束在计算火期时也必须满足闰年
请帮助我成为 SQL 服务器功能的新手
我试过的代码
DECLARE @INVOICEDATE DATETIME ='02/01/2016'
,@TENANTID BIGINT=29
,@PAYMENTTERMID BIGINT=2
BEGIN
DECLARE @DUEDATE DATETIME
DECLARE @ACTUALDUEDATE BIGINT
DECLARE @CALCULATEDDATE DATETIME
DECLARE @PAYMENTTYPES BIGINT
DECLARE @DAYSOFMONTH BIGINT
DECLARE @DAYSAFTERDUEDAY BIGINT
DECLARE @NOOFDAYS BIGINT
SELECT @PAYMENTTYPES = PAYMENT_TYPES
,@NOOFDAYS = NUMBER_OF_DAYS
,@DAYSOFMONTH = DAY_OF_MONTH
,@DAYSAFTERDUEDAY = DAYS_AFTER_DUE_DAY
FROM XC_PAYMENT_TERMS_MASTER
WHERE TENANT_ID = @TENANTID
AND PAYMENT_TERM_ID = @PAYMENTTERMID
IF @PAYMENTTYPES = 1
BEGIN
SET @CALCULATEDDATE = DATEADD(dd, @NOOFDAYS, @INVOICEDATE)
END
ELSE IF @PAYMENTTYPES = 2
BEGIN
SET @ACTUALDUEDATE = @DAYSOFMONTH - @DAYSAFTERDUEDAY
IF 1 = (
IIF(DATEPART(dd, (
EOMONTH(CONCAT (
DATEPART(yyyy, @INVOICEDATE)
,'0201'
))
)) = 29, 1, 0)
)
--LEAP YEAR
BEGIN
IF(@ACTUALDUEDATE <= 0)
BEGIN
IF DATEPART(dd, @INVOICEDATE) = 30
AND DATEPART(mm, @INVOICEDATE) =01
BEGIN
SET @CALCULATEDDATE=DATEADD(dd, 31, @INVOICEDATE)
END
ELSE IF DATEPART(dd, @INVOICEDATE) = 31
AND DATEPART(mm, @INVOICEDATE) =01
BEGIN
SET @CALCULATEDDATE=DATEADD(dd, 31, @INVOICEDATE)
END
ELSE
BEGIN
IF @DAYSOFMONTH = 30 OR @DAYSOFMONTH =31
BEGIN
SET @CALCULATEDDATE= DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0, @INVOICEDATE)+2,0))
END
ELSE
BEGIN
DECLARE @NEWNEGATIVEDATE DATETIME
SET @NEWNEGATIVEDATE = DATEADD(DAY, @DAYSOFMONTH - DATEPART(DAY, @INVOICEDATE), @INVOICEDATE);
SET @DUEDATE = DATEADD(mm, 1, @NEWNEGATIVEDATE)
END
END
END
ELSE IF(@ACTUALDUEDATE > 0)
BEGIN
SELECT 2
DECLARE @COMBINEDDATE DATETIME
SET @COMBINEDDATE=DATEADD(DAY, @ACTUALDUEDATE - DATEPART(DAY, @INVOICEDATE), @INVOICEDATE);
SELECT @INVOICEDATE AS INVDATE
SELECT @COMBINEDDATE AS COMBDATE
IF @INVOICEDATE > @COMBINEDDATE
BEGIN
SELECT 115 AS TRUE
DECLARE @NEWDATE DATETIME
SET @NEWDATE = DATEADD(DAY, @DAYSOFMONTH - DATEPART(DAY, @INVOICEDATE), @INVOICEDATE);
SET @DUEDATE = DATEADD(mm, 1, @NEWDATE)
SELECT @DUEDATE AS DATES
END
ELSE
BEGIN
SET @DUEDATE=DATEADD(DAY, @DAYSOFMONTH - DATEPART(DAY, @INVOICEDATE), @INVOICEDATE);
SELECT @DUEDATE AS DATEDUE
END
END
END
ELSE
--NOT LEAP YEAR
BEGIN
END
END
END
最终通过创建以下函数解决了它
CREATE FUNCTION [dbo].[XC_CALCULATE_DUE_DATE] (
@INVOICEDATE DATETIME
,@TENANTID BIGINT
,@PAYMENTTERMID BIGINT
)
RETURNS DATETIME
AS
BEGIN
DECLARE @DAYOFMONTH BIGINT
DECLARE @DAYOFNEXTMONTH BIGINT
DECLARE @PAYMENTTYPES BIGINT
DECLARE @NOOFDAYS BIGINT
SELECT @PAYMENTTYPES = PAYMENT_TYPES
,@NOOFDAYS = NUMBER_OF_DAYS
,@DAYOFMONTH = DAY_OF_MONTH
,@DAYOFNEXTMONTH = DAYS_AFTER_DUE_DAY
FROM XC_PAYMENT_TERMS_MASTER
WHERE TENANT_ID = @TENANTID
AND PAYMENT_TERM_ID = @PAYMENTTERMID
DECLARE @DIFFERENCE BIGINT = ISNULL(@DAYOFMONTH, 0) - ISNULL(@DAYOFNEXTMONTH, 0)
DECLARE @DUEDATE DATETIME
DECLARE @ACTUALDUEDATE BIGINT
DECLARE @CALCULATEDDATE DATETIME
IF @PAYMENTTYPES = 1
BEGIN
SET @DUEDATE = DATEADD(dd, @NOOFDAYS, @INVOICEDATE)
END
ELSE IF @PAYMENTTYPES = 2
BEGIN
DECLARE @LEAPYEAR TINYINT = IIF(DATEPART(dd, (
EOMONTH(CONCAT (
DATEPART(yyyy, @INVOICEDATE)
,'0201'
))
)) = 29, 1, 0)
IF @DIFFERENCE <= 0
BEGIN
DECLARE @STARTINGDATE DATETIME
DECLARE @NEWDATE DATETIME
DECLARE @NEXTMONTH DATETIME
IF 1 = @LEAPYEAR
BEGIN
SET @STARTINGDATE = DATEADD(month, DATEDIFF(month, 0, @INVOICEDATE), 0)
SET @NEXTMONTH = DATEADD(MONTH, 1, @STARTINGDATE)
IF 1 = DATEPART(MONTH, @INVOICEDATE)
BEGIN
IF @DAYOFMONTH = 30
BEGIN
SET @DUEDATE = DATEADD(month, DATEDIFF(month, 0, DATEADD(MONTH, 2, @INVOICEDATE)), 0)
END
ELSE IF @DAYOFMONTH = 31
BEGIN
SET @DUEDATE = DATEADD(DAY, 1, DATEADD(month, DATEDIFF(month, 0, DATEADD(MONTH, 2, @INVOICEDATE)), 0))
END
ELSE
BEGIN
SET @DUEDATE = DATEADD(DAY, @DAYOFMONTH - 1, @NEXTMONTH)
END
END
ELSE
BEGIN
SET @DUEDATE = DATEADD(DAY, @DAYOFMONTH - 1, @NEXTMONTH)
END
END
ELSE
BEGIN
SET @STARTINGDATE = DATEADD(month, DATEDIFF(month, 0, @INVOICEDATE), 0)
SET @NEXTMONTH = DATEADD(MONTH, 1, @STARTINGDATE)
IF 1 = DATEPART(MONTH, @INVOICEDATE)
BEGIN
IF @DAYOFMONTH = 29
BEGIN
SET @DUEDATE = DATEADD(month, DATEDIFF(month, 0, DATEADD(MONTH, 2, @INVOICEDATE)), 0)
END
ELSE IF @DAYOFMONTH = 30
BEGIN
SET @DUEDATE = DATEADD(DAY, 1, DATEADD(month, DATEDIFF(month, 0, DATEADD(MONTH, 2, @INVOICEDATE)), 0))
END
ELSE IF @DAYOFMONTH = 31
BEGIN
SET @DUEDATE = DATEADD(DAY, 2, DATEADD(month, DATEDIFF(month, 0, DATEADD(MONTH, 2, @INVOICEDATE)), 0))
END
ELSE
BEGIN
SET @DUEDATE = DATEADD(DAY, @DAYOFMONTH - 1, @NEXTMONTH)
END
END
ELSE
BEGIN
SET @DUEDATE = DATEADD(DAY, @DAYOFMONTH - 1, @NEXTMONTH)
END
END
END
ELSE
BEGIN
DECLARE @SDATES DATETIME = DATEADD(month, DATEDIFF(month, 0, @INVOICEDATE), 0)
DECLARE @NMONTH DATETIME = DATEADD(MONTH, 1, @SDATES)
IF DATEPART(DD, @INVOICEDATE) > @DIFFERENCE
BEGIN
IF @DAYOFMONTH > 30
AND DATEPART(DD, @INVOICEDATE) <> @DIFFERENCE
BEGIN
SET @DUEDATE = DATEADD(s, - 1, DATEADD(mm, DATEDIFF(m, 0, @NMONTH) + 1, 0))
END
ELSE
BEGIN
SET @DUEDATE = DATEADD(DAY, @DAYOFMONTH - 1, @NMONTH)
END
END
ELSE
BEGIN
IF @DAYOFMONTH > 30
AND DATEPART(DD, @INVOICEDATE) <> @DIFFERENCE
BEGIN
SET @DUEDATE = DATEADD(s, - 1, DATEADD(mm, DATEDIFF(m, 0, @NMONTH) + 1, 0))
END
ELSE IF @DAYOFMONTH > 30
AND DATEPART(DD, @INVOICEDATE) = @DIFFERENCE
BEGIN
SET @DUEDATE = DATEADD(s, - 1, DATEADD(mm, DATEDIFF(m, 0, @SDATES) + 1, 0))
END
ELSE
BEGIN
SET @DUEDATE = DATEADD(DAY, @DAYOFMONTH - 1, @SDATES)
END
END
IF 1 = @LEAPYEAR
BEGIN
IF 1 = DATEPART(MONTH, @INVOICEDATE)
AND DATEPART(DD, @INVOICEDATE) <> @DIFFERENCE
BEGIN
IF @DAYOFMONTH > 29
BEGIN
SET @DUEDATE = DATEADD(s, - 1, DATEADD(mm, DATEDIFF(m, 0, @NMONTH) + 1, 0))
END
END
END
ELSE
BEGIN
IF 1 = DATEPART(MONTH, @INVOICEDATE)
AND DATEPART(DD, @INVOICEDATE) <> @DIFFERENCE
BEGIN
IF @DAYOFMONTH >= 29
BEGIN
SET @DUEDATE = DATEADD(s, - 1, DATEADD(mm, DATEDIFF(m, 0, @NMONTH) + 1, 0))
END
END
END
END
END
RETURN @DUEDATE
END
我正在尝试根据以下限制使用发票日期计算到期日
会有两个文本框,一个是输入月几,另一个是输入到期月的前一天
如果该月的第几天是 4 并且到期月份的前一天是 5 我们必须通过减去 4 和 5 来计算值,如果减去的值为 -ve 1 并且如果输入发票日期是 11/13/2016,因此截止日期必须是 12/04/2017(这里的 04 是星期几)
如果该月的第几天是 15 并且到期月份的前一天是 5 并且减去的值为 10(非负数)输入的发票日期是 11/13/2016 意味着到期日期必须为 12/15/2016(这里的 15 是月份中的第几天)如果发票日期小于或等于减去的值,即 10,如发票日期 11/09/2016,则发票日期必须为 11/15/2016
注意上述约束在计算火期时也必须满足闰年
请帮助我成为 SQL 服务器功能的新手
我试过的代码
DECLARE @INVOICEDATE DATETIME ='02/01/2016'
,@TENANTID BIGINT=29
,@PAYMENTTERMID BIGINT=2
BEGIN
DECLARE @DUEDATE DATETIME
DECLARE @ACTUALDUEDATE BIGINT
DECLARE @CALCULATEDDATE DATETIME
DECLARE @PAYMENTTYPES BIGINT
DECLARE @DAYSOFMONTH BIGINT
DECLARE @DAYSAFTERDUEDAY BIGINT
DECLARE @NOOFDAYS BIGINT
SELECT @PAYMENTTYPES = PAYMENT_TYPES
,@NOOFDAYS = NUMBER_OF_DAYS
,@DAYSOFMONTH = DAY_OF_MONTH
,@DAYSAFTERDUEDAY = DAYS_AFTER_DUE_DAY
FROM XC_PAYMENT_TERMS_MASTER
WHERE TENANT_ID = @TENANTID
AND PAYMENT_TERM_ID = @PAYMENTTERMID
IF @PAYMENTTYPES = 1
BEGIN
SET @CALCULATEDDATE = DATEADD(dd, @NOOFDAYS, @INVOICEDATE)
END
ELSE IF @PAYMENTTYPES = 2
BEGIN
SET @ACTUALDUEDATE = @DAYSOFMONTH - @DAYSAFTERDUEDAY
IF 1 = (
IIF(DATEPART(dd, (
EOMONTH(CONCAT (
DATEPART(yyyy, @INVOICEDATE)
,'0201'
))
)) = 29, 1, 0)
)
--LEAP YEAR
BEGIN
IF(@ACTUALDUEDATE <= 0)
BEGIN
IF DATEPART(dd, @INVOICEDATE) = 30
AND DATEPART(mm, @INVOICEDATE) =01
BEGIN
SET @CALCULATEDDATE=DATEADD(dd, 31, @INVOICEDATE)
END
ELSE IF DATEPART(dd, @INVOICEDATE) = 31
AND DATEPART(mm, @INVOICEDATE) =01
BEGIN
SET @CALCULATEDDATE=DATEADD(dd, 31, @INVOICEDATE)
END
ELSE
BEGIN
IF @DAYSOFMONTH = 30 OR @DAYSOFMONTH =31
BEGIN
SET @CALCULATEDDATE= DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0, @INVOICEDATE)+2,0))
END
ELSE
BEGIN
DECLARE @NEWNEGATIVEDATE DATETIME
SET @NEWNEGATIVEDATE = DATEADD(DAY, @DAYSOFMONTH - DATEPART(DAY, @INVOICEDATE), @INVOICEDATE);
SET @DUEDATE = DATEADD(mm, 1, @NEWNEGATIVEDATE)
END
END
END
ELSE IF(@ACTUALDUEDATE > 0)
BEGIN
SELECT 2
DECLARE @COMBINEDDATE DATETIME
SET @COMBINEDDATE=DATEADD(DAY, @ACTUALDUEDATE - DATEPART(DAY, @INVOICEDATE), @INVOICEDATE);
SELECT @INVOICEDATE AS INVDATE
SELECT @COMBINEDDATE AS COMBDATE
IF @INVOICEDATE > @COMBINEDDATE
BEGIN
SELECT 115 AS TRUE
DECLARE @NEWDATE DATETIME
SET @NEWDATE = DATEADD(DAY, @DAYSOFMONTH - DATEPART(DAY, @INVOICEDATE), @INVOICEDATE);
SET @DUEDATE = DATEADD(mm, 1, @NEWDATE)
SELECT @DUEDATE AS DATES
END
ELSE
BEGIN
SET @DUEDATE=DATEADD(DAY, @DAYSOFMONTH - DATEPART(DAY, @INVOICEDATE), @INVOICEDATE);
SELECT @DUEDATE AS DATEDUE
END
END
END
ELSE
--NOT LEAP YEAR
BEGIN
END
END
END
最终通过创建以下函数解决了它
CREATE FUNCTION [dbo].[XC_CALCULATE_DUE_DATE] (
@INVOICEDATE DATETIME
,@TENANTID BIGINT
,@PAYMENTTERMID BIGINT
)
RETURNS DATETIME
AS
BEGIN
DECLARE @DAYOFMONTH BIGINT
DECLARE @DAYOFNEXTMONTH BIGINT
DECLARE @PAYMENTTYPES BIGINT
DECLARE @NOOFDAYS BIGINT
SELECT @PAYMENTTYPES = PAYMENT_TYPES
,@NOOFDAYS = NUMBER_OF_DAYS
,@DAYOFMONTH = DAY_OF_MONTH
,@DAYOFNEXTMONTH = DAYS_AFTER_DUE_DAY
FROM XC_PAYMENT_TERMS_MASTER
WHERE TENANT_ID = @TENANTID
AND PAYMENT_TERM_ID = @PAYMENTTERMID
DECLARE @DIFFERENCE BIGINT = ISNULL(@DAYOFMONTH, 0) - ISNULL(@DAYOFNEXTMONTH, 0)
DECLARE @DUEDATE DATETIME
DECLARE @ACTUALDUEDATE BIGINT
DECLARE @CALCULATEDDATE DATETIME
IF @PAYMENTTYPES = 1
BEGIN
SET @DUEDATE = DATEADD(dd, @NOOFDAYS, @INVOICEDATE)
END
ELSE IF @PAYMENTTYPES = 2
BEGIN
DECLARE @LEAPYEAR TINYINT = IIF(DATEPART(dd, (
EOMONTH(CONCAT (
DATEPART(yyyy, @INVOICEDATE)
,'0201'
))
)) = 29, 1, 0)
IF @DIFFERENCE <= 0
BEGIN
DECLARE @STARTINGDATE DATETIME
DECLARE @NEWDATE DATETIME
DECLARE @NEXTMONTH DATETIME
IF 1 = @LEAPYEAR
BEGIN
SET @STARTINGDATE = DATEADD(month, DATEDIFF(month, 0, @INVOICEDATE), 0)
SET @NEXTMONTH = DATEADD(MONTH, 1, @STARTINGDATE)
IF 1 = DATEPART(MONTH, @INVOICEDATE)
BEGIN
IF @DAYOFMONTH = 30
BEGIN
SET @DUEDATE = DATEADD(month, DATEDIFF(month, 0, DATEADD(MONTH, 2, @INVOICEDATE)), 0)
END
ELSE IF @DAYOFMONTH = 31
BEGIN
SET @DUEDATE = DATEADD(DAY, 1, DATEADD(month, DATEDIFF(month, 0, DATEADD(MONTH, 2, @INVOICEDATE)), 0))
END
ELSE
BEGIN
SET @DUEDATE = DATEADD(DAY, @DAYOFMONTH - 1, @NEXTMONTH)
END
END
ELSE
BEGIN
SET @DUEDATE = DATEADD(DAY, @DAYOFMONTH - 1, @NEXTMONTH)
END
END
ELSE
BEGIN
SET @STARTINGDATE = DATEADD(month, DATEDIFF(month, 0, @INVOICEDATE), 0)
SET @NEXTMONTH = DATEADD(MONTH, 1, @STARTINGDATE)
IF 1 = DATEPART(MONTH, @INVOICEDATE)
BEGIN
IF @DAYOFMONTH = 29
BEGIN
SET @DUEDATE = DATEADD(month, DATEDIFF(month, 0, DATEADD(MONTH, 2, @INVOICEDATE)), 0)
END
ELSE IF @DAYOFMONTH = 30
BEGIN
SET @DUEDATE = DATEADD(DAY, 1, DATEADD(month, DATEDIFF(month, 0, DATEADD(MONTH, 2, @INVOICEDATE)), 0))
END
ELSE IF @DAYOFMONTH = 31
BEGIN
SET @DUEDATE = DATEADD(DAY, 2, DATEADD(month, DATEDIFF(month, 0, DATEADD(MONTH, 2, @INVOICEDATE)), 0))
END
ELSE
BEGIN
SET @DUEDATE = DATEADD(DAY, @DAYOFMONTH - 1, @NEXTMONTH)
END
END
ELSE
BEGIN
SET @DUEDATE = DATEADD(DAY, @DAYOFMONTH - 1, @NEXTMONTH)
END
END
END
ELSE
BEGIN
DECLARE @SDATES DATETIME = DATEADD(month, DATEDIFF(month, 0, @INVOICEDATE), 0)
DECLARE @NMONTH DATETIME = DATEADD(MONTH, 1, @SDATES)
IF DATEPART(DD, @INVOICEDATE) > @DIFFERENCE
BEGIN
IF @DAYOFMONTH > 30
AND DATEPART(DD, @INVOICEDATE) <> @DIFFERENCE
BEGIN
SET @DUEDATE = DATEADD(s, - 1, DATEADD(mm, DATEDIFF(m, 0, @NMONTH) + 1, 0))
END
ELSE
BEGIN
SET @DUEDATE = DATEADD(DAY, @DAYOFMONTH - 1, @NMONTH)
END
END
ELSE
BEGIN
IF @DAYOFMONTH > 30
AND DATEPART(DD, @INVOICEDATE) <> @DIFFERENCE
BEGIN
SET @DUEDATE = DATEADD(s, - 1, DATEADD(mm, DATEDIFF(m, 0, @NMONTH) + 1, 0))
END
ELSE IF @DAYOFMONTH > 30
AND DATEPART(DD, @INVOICEDATE) = @DIFFERENCE
BEGIN
SET @DUEDATE = DATEADD(s, - 1, DATEADD(mm, DATEDIFF(m, 0, @SDATES) + 1, 0))
END
ELSE
BEGIN
SET @DUEDATE = DATEADD(DAY, @DAYOFMONTH - 1, @SDATES)
END
END
IF 1 = @LEAPYEAR
BEGIN
IF 1 = DATEPART(MONTH, @INVOICEDATE)
AND DATEPART(DD, @INVOICEDATE) <> @DIFFERENCE
BEGIN
IF @DAYOFMONTH > 29
BEGIN
SET @DUEDATE = DATEADD(s, - 1, DATEADD(mm, DATEDIFF(m, 0, @NMONTH) + 1, 0))
END
END
END
ELSE
BEGIN
IF 1 = DATEPART(MONTH, @INVOICEDATE)
AND DATEPART(DD, @INVOICEDATE) <> @DIFFERENCE
BEGIN
IF @DAYOFMONTH >= 29
BEGIN
SET @DUEDATE = DATEADD(s, - 1, DATEADD(mm, DATEDIFF(m, 0, @NMONTH) + 1, 0))
END
END
END
END
END
RETURN @DUEDATE
END