-1

可能重复:
SQL 消息 8114,级别 16,状态 5,过程 sp_product_listing,第 0 行错误将数据类型 varchar 转换为日期时间

我看到这是前段时间在我学校另一个学期有人问的,哈哈。但他们得到的答案并没有真正让我满意。这是另一个问题的链接:SQL Msg 8114, Level 16, State 5, Procedure sp_product_listing, Line 0 Error convert 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 转换为日期时间时出错。

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

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
4

2 回答 2

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

尽管有上述情况,关于您得到的直接错误:

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

除此之外,您正在运行的方式EXEC,您尝试将值传递给@month并且@year仅表示日期的月份和年份组件(分别),而 SQL 引擎期望有效(即完整)日期。

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

于 2012-12-10T19:11:18.630 回答
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;
于 2012-12-10T19:13:28.843 回答