遇到特定存储过程的问题。我想我大概都是正确的...... 我基本上希望能够搜索一个月和一年,并在该时间线内出售任何产品的行。
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
我想我知道自己需要做什么,只是不知道该怎么做...... 救命啊!
答案 0 :(得分:1)
MONTH()返回一个int。
代替MONTH(o.OrderDate),尝试DATENAME(m,o.OrderDate)
编辑:
另请注意,如果不使用LIKE运算符,则使用通配符时输入将不会产生结果。
使用以下行更新您的程序:
WHERE p.ProductName LIKE @productname
答案 1 :(得分:1)
以下两个条件可能使您的查询不是sargable,因为在每种情况下,您都要将函数应用于要过滤的列:
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
答案 2 :(得分:0)
要将月份字符串转换为月份的1-12表示,请使用内置函数DATENAME
- 使用类似于1922年12月1日的内容重建日期,然后将其用于输入{{1} }
答案 3 :(得分:0)
由jlnorsworthy回答
&#34;而不是MONTH(o.OrderDate),尝试DATENAME(m,o.OrderDate)&#34;
这将有效
如果没有结果,请检查您传递的输入
EXEC sp_products &#39;%豆腐%&#39; ,&#39; 12月&#39;,1992
您正在将它与=运算符
进行比较WHERE p.ProductName = @productname
改变=喜欢它会起作用。