如何将 DATE 参数默认设置为 SQL 服务器中的动态计算值
How to set DATE parameter default to dynamically calculated value in SQL Server
我有一个包含两个 DATE 参数的存储过程,我希望它们具有默认值。但是,我也希望能够根据需要覆盖这些值。我正在使用 SSMS 18。下面是我希望我的代码如何工作。 (这不是一个工作示例)
CREATE PROCEDURE dbo.usp_stuff_and_things
-- Add the parameters for the stored procedure here
@begin_date DATE = (SELECT DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE())-1, 0) )
,@end_date DATE = (SELECT DATEADD(MONTH, DATEDIFF(MONTH, -1, GETDATE())-1, -1) )
AS
BEGIN
SET NOCOUNT ON;
-- Insert statements for procedure here
这两个参数分别是抢上月的第一天(@begin_date)和上月的最后一天(@end_date)。这些默认值大部分时间都有效,但有时我需要拉出自定义日期范围。我希望能够根据需要将这样的值传递给存储过程。
EXEC dbo.usp_stuff_and_things @begin_date = '2021-01-01', @end_date = '2021-12-31'
有没有办法做到这一点?
默认值不能使用表达式。尝试:
CREATE PROCEDURE dbo.usp_stuff_and_things
@begin_date date = NULL,
@end_date date = NULL
AS
BEGIN
SET NOCOUNT ON;
SET @end_date = COALESCE(@end_date,
EOMONTH(GETDATE(), -2));
SET @begin_date = COALESCE(@begin_date,
DATEADD(DAY, 1, @end_date));
END
GO
EOMONTH()
在大多数情况下恕我直言,没有太多价值,但它是一种动态确定月份边界的简单方法。其他一些比混乱和神秘的 dateadd/datediff 方法更好的方法:
我也真的建议避免使用 yyyy-mm-dd
格式,因为它在某些情况下可能会被误解为 yyyy-dd-mm
:
虽然我不得不说,结束日期后一天的开始日期没有多大意义。
过程的DEFAULT
值必须是文字,不能是表达式,当然不能从[=12解析=] 语句。相反,您可以 DEFAULT
将值 NULL
赋值给过程定义中的表达式,如果值为 NULL
:
CREATE PROCEDURE dbo.usp_stuff_and_things
-- Add the parameters for the stored procedure here
@begin_date DATE = NULL,
@end_date DATE = NULL
AS
BEGIN
SET NOCOUNT ON;
IF @begin_date IS NULL
SET @begin_date = DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE())-1, 0);
IF @end_date IS NULL
SET @end_date = DATEADD(MONTH, DATEDIFF(MONTH, -1, GETDATE())-1, -1);
-- Insert statements for procedure here
END;
GO
我有一个包含两个 DATE 参数的存储过程,我希望它们具有默认值。但是,我也希望能够根据需要覆盖这些值。我正在使用 SSMS 18。下面是我希望我的代码如何工作。 (这不是一个工作示例)
CREATE PROCEDURE dbo.usp_stuff_and_things
-- Add the parameters for the stored procedure here
@begin_date DATE = (SELECT DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE())-1, 0) )
,@end_date DATE = (SELECT DATEADD(MONTH, DATEDIFF(MONTH, -1, GETDATE())-1, -1) )
AS
BEGIN
SET NOCOUNT ON;
-- Insert statements for procedure here
这两个参数分别是抢上月的第一天(@begin_date)和上月的最后一天(@end_date)。这些默认值大部分时间都有效,但有时我需要拉出自定义日期范围。我希望能够根据需要将这样的值传递给存储过程。
EXEC dbo.usp_stuff_and_things @begin_date = '2021-01-01', @end_date = '2021-12-31'
有没有办法做到这一点?
默认值不能使用表达式。尝试:
CREATE PROCEDURE dbo.usp_stuff_and_things
@begin_date date = NULL,
@end_date date = NULL
AS
BEGIN
SET NOCOUNT ON;
SET @end_date = COALESCE(@end_date,
EOMONTH(GETDATE(), -2));
SET @begin_date = COALESCE(@begin_date,
DATEADD(DAY, 1, @end_date));
END
GO
EOMONTH()
在大多数情况下恕我直言,没有太多价值,但它是一种动态确定月份边界的简单方法。其他一些比混乱和神秘的 dateadd/datediff 方法更好的方法:
我也真的建议避免使用 yyyy-mm-dd
格式,因为它在某些情况下可能会被误解为 yyyy-dd-mm
:
虽然我不得不说,结束日期后一天的开始日期没有多大意义。
过程的DEFAULT
值必须是文字,不能是表达式,当然不能从[=12解析=] 语句。相反,您可以 DEFAULT
将值 NULL
赋值给过程定义中的表达式,如果值为 NULL
:
CREATE PROCEDURE dbo.usp_stuff_and_things
-- Add the parameters for the stored procedure here
@begin_date DATE = NULL,
@end_date DATE = NULL
AS
BEGIN
SET NOCOUNT ON;
IF @begin_date IS NULL
SET @begin_date = DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE())-1, 0);
IF @end_date IS NULL
SET @end_date = DATEADD(MONTH, DATEDIFF(MONTH, -1, GETDATE())-1, -1);
-- Insert statements for procedure here
END;
GO