SQL-正在将MONTH提取从数字转换为完整的月份名称



遇到特定存储过程的问题。我想我基本上是正确的。。。我基本上希望能够搜索一个月和一年,并显示在该时间线内销售的任何产品行。

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

改变=喜欢就行了。

最新更新