SQL 服务器存储过程传递日期参数

SQL Server stored procedure passing date parameters

ALTER PROCEDURE [dbo].[AccountsData]  
    @Start_Date datetime,
    @End_Date datetime
AS
BEGIN 
    SET NOCOUNT ON;
    
    SELECT 
        a.Customer_AC_No, a.Customer_Name, a.Product_Code, 
        a.Product_Description, a.Sales_Person, c.HSID
    FROM 
        (SELECT 
             Customer_AC_No, Customer_Name, Product_Code, 
             Product_Description, Sales_Person
         FROM 
             View_Sales_Details
         WHERE 
             ([Week Ending]  >=' @Start_Date') AND ([Sales Value] > 0)
         GROUP BY 
             Customer_AC_No, Product_Code, Product_Description, 
             Customer_Name, Sales_Person) AS a
   LEFT JOIN 
       (SELECT 
            Customer_AC_No, Product_Code
        FROM 
            View_Sales_Details
        WHERE 
            ([Week Ending] >= '@End_Date') AND ([Sales Value] > 0)
        GROUP BY 
            Customer_AC_No, Product_Code) AS b ON a.Customer_AC_No = b.Customer_AC_No
                                               AND a.Product_Code = b.Product_Code
    INNER JOIN 
        Hubspot.dbo.View_BPA_Cust_Data AS c ON a.Customer_AC_No = c.CustomerNo COLLATE Latin1_General_100_CI_AS
     WHERE 
         b.Customer_AC_No IS NULL 
     ORDER BY  
         a.Customer_AC_No, a.Product_Code ASC
END

我正在尝试将上述日期参数传递给上面的 SQL 服务器存储过程,但我一直收到此错误

Msg 241, Level 16, State 1, Procedure AccountsData, Line 52
Conversion failed when converting date and/or time from character string.

有人可以帮忙吗? WeekEnding 日期也是日期时间格式。谢谢

SQL 服务器支持多种格式来将日期和时间指定为字符串文字 - 请参阅 MSDN Books Online on CAST and CONVERT。大多数这些格式依赖于您的设置 - 因此,这些设置有时可能有效 - 有时无效。

解决这个问题的方法是使用 SQL 服务器支持的(稍微改编的)ISO-8601 日期格式 - 这种格式有效 总是 - 无论您的 SQL 服务器语言和日期格式设置如何。

ISO-8601 format 受 SQL 支持 服务器有两种形式:

  • YYYYMMDD 仅用于日期(无时间部分);此处注意:没有破折号!,这一点非常重要! YYYY-MM-DD NOT 独立于 SQL 服务器中的日期格式设置,并且 NOT 在所有情况下都有效!

或:

  • YYYY-MM-DDTHH:MM:SS 用于日期和时间 - 请注意:此格式 破折号(但它们 可以 被省略),和一个固定的 T 作为 DATETIME.
  • 的日期和时间部分之间的分隔符

这对 SQL Server 2000 及更新版本有效。

如果您使用 SQL Server 2008 或更新版本和 DATE 数据类型(仅 DATE - 不是 DATETIME! ),那么您确实也可以使用 YYYY-MM-DD 格式,这也适用于您 SQL 服务器中的任何设置。

不要问我为什么整个主题如此棘手和令人困惑 - 就是这样。但是使用 YYYYMMDD 格式,对于任何版本的 SQL 服务器以及 SQL 服务器中的任何语言和日期格式设置都应该没问题。

对于 SQL Server 2008 和更新版本的建议是,如果您只需要日期部分,则使用 DATE,如果您同时需要日期和时间,则使用 DATETIME2(n)。如果可能的话,您应该尝试开始逐步淘汰 DATETIME 数据类型。

所以在你的情况下,要么切换到使用 DATE 作为你的参数数据类型(因为你显然不使用时间部分):

ALTER PROCEDURE [dbo].[AccountsData]  
    @Start_Date DATE,
    @End_Date DATE

然后像这样执行你的存储过程:

EXEC [dbo].[AccountsData] '2019-05-11', '2020-06-10'

或使用此格式来支持 DATETIME 如果您坚持保留该格式:

EXEC [dbo].[AccountsData] '2019-05-11T00:00:00', '2020-06-10T00:00:00'

您的 select 有误。您已将查询更改为这样

 DATEPART(wk, Ending)>=DATEPART(wk, @Start_Date) AND ([Sales Value] > 0)
 DATEPART(wk, Ending)>=DATEPART(wk, @End_Date) AND ([Sales Value] > 0)