【问题标题】:Msg 8114, Level 16, State 5, Procedure sp_product_listing, Line 0 Error converting data type varchar to datetime [duplicate]消息 8114,级别 16,状态 5,过程 sp_product_listing,第 0 行错误将数据类型 varchar 转换为 datetime [重复]
【发布时间】:2012-12-10 19:01:25
【问题描述】:

可能重复:
SQL Msg 8114, Level 16, State 5, Procedure sp_product_listing, Line 0 Error converting data type varchar to datetime

我看到前段时间有人在我学校的另一个学期问过这个问题,哈哈。但他们得到的答案并没有真正让我满意。这是另一个问题的链接:SQL Msg 8114, Level 16, State 5, Procedure sp_product_listing, Line 0 Error converting data type varchar to datetime

答案所说的大部分内容对我来说没有多大意义,因为我对 SQL 很陌生。如果我们能就此展开另一次讨论,那就太好了。尤其是减去最近在我的问题中发生的老师抨击......

以下语句成功完成,但是:

CREATE PROCEDURE sp_product_listing
(
     @product varchar(30),
     @month   datetime,
     @year    datetime
)
AS
  SELECT
     'product_name' = products.name,
     products.unit_price,
     products.quantity_in_stock,
     'supplier_name' = suppliers.name
  FROM
     suppliers
  INNER JOIN
     products ON suppliers.supplier_id = products.supplier_id
  INNER JOIN
     order_details ON products.product_id = order_details.product_id
  INNER JOIN
     orders ON order_details.order_id = orders.order_id
  WHERE
     products.name = @product 
     AND MONTH ('orders.order_date') = @month 
     AND YEAR ('orders.order_date') = @year;
GO

当我尝试执行该过程时,我收到一条错误消息:

消息 8114,级别 16,状态 5,过程 sp_product_listing,第 0 行
将数据类型 varchar 转换为 datetime 时出错。

这是我执行存储过程的方式:

EXECUTE sp_product_listing @product = 'Jack%', @month = 'June', @year = 2001;
GO

我尝试将两个 datetime 数据类型更改为 varchars,但没有成功,因为列本身最初是 datetime 数据类型。我不确定我在这里缺少什么?

更新:

这是https://stackoverflow.com/users/1554034/valex指导的最终解决方案。

CREATE PROCEDURE sp_product_listing
(
   @product  varchar(30),
   @month    int,
   @year     int
)
AS
   SELECT               
      'product_name' = products.name,
      products.unit_price,
      products.quantity_in_stock,
      'supplier_name' = suppliers.name
   FROM
      suppliers
   INNER JOIN
      products ON suppliers.supplier_id = products.supplier_id
   INNER JOIN 
      order_details ON products.product_id = order_details.product_id
   INNER JOIN 
      orders ON order_details.order_id = orders.order_id
   WHERE
      products.name LIKE @product 
      AND MONTH (orders.order_date) = @month 
      AND YEAR (orders.order_date) = @year;
  GO

此外,对于仍在阅读的任何人,这是我的老师给我的解决方案,它给出了相同的结果。

CREATE PROCEDURE sp_product_listing
(
@product    varchar(30),
@month      varchar(10),
@year       char(4)
)
AS
    SELECT
       'product_name' = products.name,
       products.unit_price,
       products.quantity_in_stock,
       'supplier_name' = suppliers.name
    FROM
       suppliers
    INNER JOIN
       products ON suppliers.supplier_id = products.supplier_id
    INNER JOIN
       order_details ON products.product_id = order_details.product_id
    INNER JOIN
       orders ON order_details.order_id = orders.order_id
    WHERE   
       products.name LIKE @product 
       AND DATENAME(MONTH,orders.order_date) = @month 
       AND YEAR (orders.order_date) = @year;
   GO

【问题讨论】:

标签: sql sql-server datetime error-handling varchar


【解决方案1】:

您收到此错误是因为 'June' 不是 DATEIME 值并且 MONTH 函数返回 int。此外,如果您输入 @product 作为 MASK(带有 '%'),您应该使用 LIKE 而不是 = 所以您应该将您的过程声明为:

CREATE PROCEDURE    sp_product_listing
(
@product    varchar(30),
@month      int,
@year       int
)

....
WHERE               products.name LIKE @product AND
....

然后叫它

EXECUTE             sp_product_listing @product = 'Jack%', @month = 6, @year = 2001;

【讨论】:

  • 我试过了,但得到了这个错误:消息 241,级别 16,状态 1,过程 sp_product_listing,第 8 行从字符串转换日期和/或时间时转换失败。
  • 你为什么打电话给MONTH ('orders.order_date')' 只是使用MONTH (orders.order_date)。在您的情况下,MONTH 尝试将 STRING 'orders.order_date' 转换为日期。
  • 天哪,就是这样。 Jeeeeeeze SQL 可以是 finnicky 嘿!非常感谢!
【解决方案2】:

这里似乎有很多问题。

我假设列orders.order_date 的类型是datetime。因此函数MONTH (orders.order_date)YEAR (orders.order_date) 的结果将是整数。

这意味着如果你想要线条

MONTH (orders.order_date) = @month AND
YEAR (orders.order_date) = @year;

为了有意义地工作,你的参数 @month@year 应该是整数。

除此之外,您似乎在传递 @product 时使用了通配符,该通配符仅对 where 子句中的 LIKE 有意义,而不是 =

最后,不确定您为什么在函数调用中引用 'orders.order_date' - 我认为没有必要引用。

我建议您进行此更改:

CREATE PROCEDURE    sp_product_listing
(
@product    varchar(30),
@month      int,
@year       int
)
AS
...
WHERE       products.name LIKE @product
...
            MONTH (orders.order_date) = @month AND
            YEAR (orders.order_date) = @year;

并拨打EXEC如下:

EXECUTE sp_product_listing @product = 'Jack%', @month = 6, @year = 2001;
GO

尽管有上述情况,关于您收到的即时错误:

在过程定义中,它们被定义为datetime 类型,这意味着在调用过程时,SQL 引擎将期望为它们接收datetime 值。

除此之外,您运行EXEC 的方式是尝试将值传递给@month@year,它们分别代表日期的月份和年份部分,而SQL引擎预计有效(即完整)日期。

您遇到的错误只是 SQL 引擎抱怨它无法将您的输入值 'June' 解释为有效的完整日期(尝试将 2001 解释为有效的完整日期也是如此)

【讨论】:

  • 好的,那我应该怎么做呢?我已经为此工作了好几个小时。
  • @isolatedhowl - 请参阅最新编辑以获取有关更改内容的建议。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-05
  • 1970-01-01
  • 2017-06-01
相关资源
最近更新 更多