Sql server SQL Msg 8114,级别16,状态5,过程sp_产品_清单,第0行将数据类型varchar转换为datetime时出错

Sql server SQL Msg 8114,级别16,状态5,过程sp_产品_清单,第0行将数据类型varchar转换为datetime时出错,sql-server,Sql Server,/我是SQL新手,有人要求我创建一个过程,但当我尝试运行execute时,它不起作用。 谁能帮我一下吗/ 运行时出错 当我运行execute 执行sp_产品清单 “杰克”, “六月”, ‘2001’ 这是我收到的错误消息 Msg 8114,16级,状态5,程序sp_产品清单,第0行 将数据类型varchar转换为datetime时出错 月份和年份是我一直在做的事情 问题在于: @month datetime, @year datetime 这两个参数都声明为datetime,但datetim

/我是SQL新手,有人要求我创建一个过程,但当我尝试运行execute时,它不起作用。 谁能帮我一下吗/

运行时出错 当我运行execute 执行sp_产品清单 “杰克”, “六月”, ‘2001’

这是我收到的错误消息

Msg 8114,16级,状态5,程序sp_产品清单,第0行 将数据类型varchar转换为datetime时出错

月份和年份是我一直在做的事情

问题在于:

@month datetime,
@year datetime 
这两个参数都声明为
datetime
,但
datetime
变量保存完整的日期和时间信息(年、月、日、小时、分钟、秒…)

您正在为
@month
参数传递'June',该参数无效,因为'June'是
字符串
@month
日期时间
。这就是错误消息所说的。

问题在于:

@month datetime,
@year datetime 
这两个参数都声明为
datetime
,但
datetime
变量保存完整的日期和时间信息(年、月、日、小时、分钟、秒…)


您正在为
@month
参数传递'June',该参数无效,因为'June'是
字符串
@month
日期时间
。这就是错误消息所说的。

如果您的
order\u date
列有索引,您最好使用
MONTH()
DATEPART()
等的范围查询。您可以将MONTH/year组合作为单个日期时间传递,也可以简单地将参数更改为整数,如下所示

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
创建过程dbo.sp\u产品清单
@乘积VARCHAR(40)='%',
@斯莫林,
@月锡
作为
开始
不计数;
声明@d SMALLDATETIME;
设置@d=DATEADD(月、@MONTH-1、,
日期(年份,@YEAR-1900,'19000101');
选择。。。
其中Orders.order_date>=@d
和Orders.order_date
如果您的
order\u date
列有一个索引,您最好使用
MONTH()
DATEPART()
等的范围查询。您可以将MONTH/year组合作为单个日期时间传递,也可以简单地将参数更改为整数,如下所示

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
创建过程dbo.sp\u产品清单
@乘积VARCHAR(40)='%',
@斯莫林,
@月锡
作为
开始
不计数;
声明@d SMALLDATETIME;
设置@d=DATEADD(月、@MONTH-1、,
日期(年份,@YEAR-1900,'19000101');
选择。。。
其中Orders.order_date>=@d
和Orders.order_date
避免按部分筛选日期,因为这将导致日期列上的索引不可用。如果将@month和@year定义为varchars或int,则可以为整个月份构造一个日期时间范围,并使用此范围筛选orders.order\u 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)
创建程序sp\u产品清单
(
@乘积varchar(40)='%',
@瓦查尔月(10),
@年份varchar(4)
)
作为
声明@firstOfMonth日期时间
设置@firstOfMonth=convert(日期时间,@month+'1',+@year,100)
挑选
products.name作为产品名称,
产品.单价,
每单位产品数量,
suppliers.name作为supplier\u name
来自产品
内部连接产品上的供应商。供应商\u id=供应商。供应商\u id
产品的内部联接订单\详细信息。产品\ id=订单\详细信息。产品\ id
订单详细信息上的内部联接订单。订单id=订单。订单id
WHERE products.name如@product
及
orders.order\u date>=@firstOfMonth
下个月一号之前
orders.order_date
避免按部分筛选日期,因为这将导致日期列上的索引不可用。如果将@month和@year定义为varchars或int,则可以为整个月份构造一个日期时间范围,并使用此范围筛选orders.order\u 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)
创建程序sp\u产品清单
(
@乘积varchar(40)='%',
@瓦查尔月(10),
@年份varchar(4)
)
作为
声明@firstOfMonth日期时间
设置@firstOfMonth=convert(日期时间,@month+'1',+@year,100)
挑选
products.name作为产品名称,
产品.单价,
每单位产品数量,
suppliers.name作为supplier\u name
来自产品
内部连接产品上的供应商。供应商\u id=供应商。供应商\u id
产品的内部联接订单\详细信息。产品\ id=订单\详细信息。产品\ id
订单详细信息上的内部联接订单。订单id=订单。订单id
WHERE products.name如@product
及
orders.order\u date>=@firstOfMonth
下个月一号之前
orders.order_date
@Elgin输入一个datetime参数或两个数字(请参阅我的答案-再次为格式问题道歉)。谢谢@Christian。转到meta,查看是否有任何主题抱怨移动设备上的格式设置。不好玩。@Elgin传入一个datetime参数或两个数字(请参阅我的答案-再次为格式问题道歉)。谢谢@Christian。转到meta,查看是否有任何主题抱怨移动设备上的格式设置。不好玩。我仍然不喜欢传递字符串“June”和所有暗示的承诺(这取决于区域和语言设置是否固定)。啊…我需要一些时间来挖掘它哈哈…我在这方面还是很新的。老师让我们用‘June’而不是数字来运行和测试……:(哈哈,这也是我的项目,arg我想使用datename也可以,但老师根本没有教任何关于datename的内容,只是告诉我们datepart,diff和addI仍然不喜欢传递字符串‘June’和所有暗示的承诺(这取决于区域和语言设置是否固定)。啊…我需要一些时间来数字化它哈哈…我在这方面还是很新的。而且