/ 我是SQL的新手,我被要求创建一个程序以某种方式成功创建过程但是当我尝试运行执行时它不起作用。 有人可以帮我一把吗? /
CREATE PROCEDURE sp_product_listing
(
@product varchar(40) ='%',
@month datetime,
@year datetime
)
AS
SELECT
products.name AS product_name,
products.unit_price,
products.quantity_per_unit,
suppliers.name AS supplier_name
FROM products
INNER JOIN suppliers ON products.supplier_id=suppliers.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=CONVERT(char(10),MONTH(orders.order_date))
AND
@year=CONVERT(char(10),YEAR(orders.order_date))
运行错误 当我运行执行 执行sp_product_listing '插口', '六月', '2001'
这是我收到的错误消息
是我坚持的月份和年份。Msg 8114,Level 16,State 5,Procedure sp_product_listing,Line 0 将数据类型varchar转换为datetime时出错。
答案 0 :(得分:2)
如果您的order_date
列包含索引,则最好使用MONTH()
,DATEPART()
等范围查询。您可以将月/年组合作为单个日期时间,或者您可以简单地将参数更改为整数,如下所示。
CREATE PROCEDURE dbo.sp_product_listing
@product VARCHAR(40) = '%',
@year SMALLINT,
@month TINYINT
AS
BEGIN
SET NOCOUNT ON;
DECLARE @d SMALLDATETIME;
SET @d = DATEADD(MONTH, @month - 1,
DATEADD(YEAR, @year-1900, '19000101'));
SELECT ...
WHERE Orders.order_date >= @d
AND Orders.order_date < DATEADD(MONTH, 1, @d);
END
GO
答案 1 :(得分:1)
问题在于:
@month datetime,
@year datetime
这两个参数都声明为datetime
,但datetime
变量包含完整的日期和时间信息(年,月,日,小时,分钟,秒......)。
您正在为@month
参数传递'June',这不起作用,因为'June'是string
且@month
是datetime
。这就是错误信息所说的内容。
答案 2 :(得分:0)
避免按部分过滤日期,因为这会使日期列上的索引无法使用。如果将@month和@year定义为varchars或ints,则可以构建整月的日期时间范围,并使用此范围过滤orders.order_date。
CREATE PROCEDURE sp_product_listing
(
@product varchar(40) ='%',
@month varchar(10),
@year varchar(4)
)
AS
declare @firstOfMonth datetime
set @firstOfMonth = convert(datetime, @month + ' 1, ' + @year, 100)
SELECT
products.name AS product_name,
products.unit_price,
products.quantity_per_unit,
suppliers.name AS supplier_name
FROM products
INNER JOIN suppliers ON products.supplier_id=suppliers.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
orders.order_date >= @firstOfMonth
AND -- before first of next month
orders.order_date < dateadd(m, 1, @firstOfMonth)