【问题标题】:SQL Server stored procedure passing date parametersSQL Server 存储过程传递日期参数
【发布时间】:2020-10-29 09:54:46
【问题描述】:
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 存储过程,但我不断收到此错误

消息 241,级别 16,状态 1,过程 AccountsData,第 52 行
从字符串转换日期和/或时间时转换失败。

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

【问题讨论】:

  • 您使用的是哪个 dbms? (该代码是特定于产品的。)
  • 你能告诉我们传递参数的代码吗?
  • EXEC [dbo].[AccountsData] '2019-05-11 00:00:00','2020-06-10 00:00:00'

标签: sql-server stored-procedures


【解决方案1】:

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

解决此问题的方法是使用 SQL Server 支持的(稍作调整的)ISO-8601 日期格式 - 这种格式始终有效 - 无论您的SQL Server 语言和日期格式设置。

SQL Server 支持的ISO-8601 format 有两种形式:

  • 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'

【讨论】:

  • 嗨 Marc,感谢您的建议,我尝试了同样的错误
  • @Randy:您还需要删除代码中引用参数的单引号 - 所以使用 ` ([Week Ending] >= @Start_Date)` ( 没有参数周围的单引号!!)
【解决方案2】:

您的选择有误。您已像这样更改查询

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

【讨论】:

    猜你喜欢
    • 2017-02-19
    • 1970-01-01
    • 1970-01-01
    • 2012-08-09
    • 1970-01-01
    • 1970-01-01
    • 2015-12-20
    • 2013-07-06
    • 1970-01-01
    相关资源
    最近更新 更多