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

时间:2012-12-10 19:01:25

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

  

可能重复:
  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

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

  

Msg 8114,Level 16,State 5,Procedure sp_product_listing,Line 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

2 个答案:

答案 0 :(得分:1)

这里似乎存在许多问题。

我认为列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时只带有一个通配符,只对LIKE有意义,而不是where子句中的=

最后,不确定为什么在函数调用中引用'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解释为有效时也是如此,完成日期)

答案 1 :(得分: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;