【问题标题】:Set DATE parameter default to dynamically calculated value将 DATE 参数默认设置为动态计算的值
【发布时间】:2022-08-23 05:04:23
【问题描述】:

我有一个带有两个 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\'

有没有办法做到这一点?

    标签: sql sql-server stored-procedures


    【解决方案1】:

    过程的 DEFAULT必须是文字,它不能是表达式,当然也不能从SELECT 语句中解析出来。相反,您可以将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
    

    【讨论】:

      【解决方案2】:

      您不能使用表达式作为默认值。尝试:

      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

      虽然我不得不说,在结束日期之后的第二天开始日期并没有多大意义。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-14
        • 1970-01-01
        • 1970-01-01
        • 2023-02-02
        相关资源
        最近更新 更多