遇到特定存储过程的问题。我想我基本上是正确的。。。我基本上希望能够搜索一个月和一年,并显示在该时间线内销售的任何产品行。
CREATE PROCEDURE sp_products
@productname CHAR(20),
@month CHAR(9),
@year CHAR(4)
AS
SELECT p.ProductName,
p.UnitPrice,
p.UnitsInStock,
s.Name
FROM Orders o
INNER JOIN OrderDetails od
ON o.OrderID = od.OrderID
INNER JOIN Products p
ON od.ProductID = p.ProductID
INNER JOIN Suppliers s
ON p.SupplierID = s.SupplierID
WHERE p.ProductName = @productname
AND MONTH(o.OrderDate) = @month
AND YEAR(o.OrderDate) = @year
给我一个"将varchar值'December'转换为数据类型int时转换失败。"错误
以下是它需要处理的查询:
EXEC sp_products '%tofu%', 'December', 1992
我想我知道我需要做什么,只是不知道怎么做…
帮助
MONTH()返回一个整数
尝试DATENAME(m,o.OrderDate)而不是MONTH(o.OrderDate
编辑:
还要注意,如果您使用通配符而不使用LIKE运算符,则您的输入不会给出结果。
用以下行更新您的程序:
WHERE p.ProductName LIKE @productname
以下两个条件可能会使您的查询不可搜索,因为在每种情况下,您都会将一个函数应用于要筛选的列:
AND MONTH(o.OrderDate) = @month
AND YEAR(o.OrderDate) = @year
我会这样改变它们:
SELECT …
…
…
FROM Orders o
/* this join actually replaces those two filters */
INNER JOIN (SELECT CAST('1-' + @month + CAST(-@year AS varchar(5))) AS Month) d
ON o.OrderDate >= d.Month AND o.OrderDate < DATEADD(MONTH, 1, d.Month)
INNER JOIN … /* the rest of your joins */
WHERE p.ProductName = @productname /* only one condition here now */
也就是说,@year
和@month
参数被格式化为一个字符串,可转换为表示相应月份第一个月的日期时间值,然后使用以下逻辑进行筛选:
order date >= the first of the given month
and
order date < the first of the next month after the given
当然,正如您已经被告知的那样,查询中的@productname
过滤器可能应该使用LIKE
比较,而不是=
,因为您似乎希望通过掩码和特定名称进行搜索。所以WHERE
子句看起来是这样的:
WHERE p.ProductName LIKE @productname
要将月份字符串转换为月份的1-12表示形式,请使用内置函数DATENAME
-用1922年12月1日之类的内容重建日期,然后将其用于DATENAME
的输入
由jlnorsworthy 回答
"请尝试DATENAME(m,o.OrderDate)",而不是MONTH(o.OrderDate)
这将工作
如果没有结果,请检查您通过的输入
EXEC sp_products"%豆腐%",1992年12月
您正在将其与=操作员进行比较
WHERE p.ProductName = @productname
改变=喜欢就行了。