我已经看到这是在我学校的另一个学期前有人问过的,哈哈。但他们得到的答案并不能让我满意。以下是其他问题的链接: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
答案 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;