sql-server - SQL Server 存储过程传递日期参数

标签 sql-server stored-procedures

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 Server 存储过程,但我不断收到此错误

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

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

最佳答案

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

解决此问题的方法是使用 SQL Server 支持的(稍作修改的)ISO-8601 日期格式 - 此格式始终有效 - 无论您的情况如何SQL Server 语言和日期格式设置。

ISO-8601 format SQL Server 支持两种类型:

  • YYYYMMDD 仅表示日期(无时间部分);请注意:不要破折号!,这非常重要! YYYY-MM-DD 独立于 SQL Server 中的日期格式设置,并且在所有情况下都有效!

或者:

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

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

如果您使用 SQL Server 2008 或更高版本以及 DATE 数据类型(仅限 DATE - DATETIME! ),那么您确实也可以使用 YYYY-MM-DD 格式,并且该格式也适用于 SQL Server 中的任何设置。

不要问我为什么整个主题如此棘手且有些令人困惑 - 事情就是这样。但使用 YYYYMMDD 格式,您应该可以适用于任何版本的 SQL Server 以及 SQL Server 中的任何语言和日期格式设置。

对于 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'

关于sql-server - SQL Server 存储过程传递日期参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64588693/

相关文章:

SQL查询按月和年分组

Sql:查找答案是否存在

SQL Server 2008 查询使用参数从 XML 中选择数据

sql-server - SQL Server 历史表 - 通过 SP 或触发器填充?

oracle - 如何使用 Oracle SQL Developer 运行存储过程?

mysql - 如何将带逗号的字符串(VARCHAR)传递给存储过程?

sql-server - 如何从现有表中设置数据库图?

sql-server - 重置SQL Server执行计划

mysql - 如何格式化这个MySQL存储过程?

c# - 如何从 C# 中的存储过程中获取选定的值?