【问题标题】:Conversion failed when converting the varchar value '29/09/2016' to data type int将 varchar 值“29/09/2016”转换为数据类型 int 时转换失败
【发布时间】:2016-09-30 11:33:03
【问题描述】:

我在使用存储过程时遇到错误。 下面是存储过程的代码:

  ALTER PROCEDURE [dbo].[usp_specificorderchangedhistory]
        -- Add the parameters for the stored procedure here
                @startRowIndex int,
    @maximumRows int, 
    @OrderDate datetime= null   
AS
BEGIN

DECLARE @first int,@last int
  SET @first = @startRowIndex * @maximumRows
  SET @last = (@startRowIndex * @maximumRows) + @maximumRows
declare @sql varchar(max)
declare @sqlcnt varchar(max)
declare @cond varchar(max)

        if @OrderDate is not null 
        begin 
            set @cond = ' and convert(varchar,so.OrderDate,101) ='+convert(varchar,@OrderDate,101)+' ' 
        end
        print @cond
set @sql= 'SELECT * FROM

(

    SELECT ROW_NUMBER() OVER (ORDER BY so.OrderID DESC) AS Row, 

   so.OrderID,

   u1.Firstname+' + ''' ''' + '+u1.Lastname as Username,

   U.Firstname as CustomerName,

   so.OrderNumber,

   so.TotalAmount,

   so.Status,

   so.OrderDate,

   so.Comment,

   p.PaymentMode as PaymentMethod,

   p.PaymentMethod as Payment_Mode,

   p.IsPaid

    FROM SpecificOrders AS so

    INNER join Users as U on so.UserID = U.UserID

    INNER join Users as u1 on so.CreatedBy = u1.UserID       

    INNER join SpecificOrderPayment as p on so.OrderID= p.OrderID  

 '+ @cond +'

) spec

WHERE Row>'+Convert(Varchar,@first )+'  AND 

  Row<='+Convert(Varchar,@last)
print @sql
exec(@sql)
set @sqlcnt= 'SELECT count(*) FROM

(

    SELECT ROW_NUMBER() OVER (ORDER BY so.OrderID DESC) AS Row

    FROM SpecificOrders AS so

    INNER join Users as U on so.UserID = U.UserID

    INNER join Users as u1 on so.CreatedBy = u1.UserID   

    INNER join SpecificOrderPayment as p on so.OrderID= p.OrderID  


 '+ @cond +'

) spec'
exec(@sqlcnt)
end

当我使用以下查询执行存储过程时:

EXEC usp_specificorderchangedhistory '08/20/2016'

得到错误:

Conversion failed when converting the varchar value '29/09/2016' to data type int.

虽然,我尝试使用

运行相同的查询没有存储过程

选择

查询。它的工作原理完全符合要求:下面是选择查询:

select * as Dateorder 
from SpecificOrders as s 
inner join SpecificOrderPayment as p 
    on s.OrderID = p.OrderID 
where convert(varchar,s.orderdate,101) =convert(varchar,'08/20/2016',101) 

谢谢

【问题讨论】:

  • 您为什么要通过将日期转换为 varchars 来比较日期?
  • 我也直接试了,没用
  • SQL Server 理解格式MM/DD/YYY orYYYY/MM/DD
  • ya 在我的数据库中,日期以类似“2016-08-20 14:54:36.363”的形式保存,而在查询中,“=”右侧的形式为“08/20” /2016'
  • 你的问题应该解释为什么你不应该对查询参数使用字符串连接。您可以避免 SQL 注入 转换问题。由于这两个值都是datetime,因此您不需要任何转换。只需使用' and so.OrderDate= @someDate ', use sp_executesql` 执行最终查询并将@OrderDate 的值作为someDate 参数传递

标签: sql-server datetime stored-procedures


【解决方案1】:

添加更多引号并使用 SELECT:

ALTER PROCEDURE [dbo].[usp_specificorderchangedhistory]
        @OrderDate datetime= null   
AS
BEGIN
    declare @cond varchar(max)
    if @OrderDate is not null 
    set @cond = ' and convert(varchar,so.OrderDate,101) ='''+convert(varchar,@OrderDate,101)+'''' 

    SELECT @cond
end

EXEC usp_specificorderchangedhistory '08/20/2016' 

输出:

 and convert(varchar,so.OrderDate,101) ='08/20/2016'

编辑

我不明白你为什么使用动态 SQL?一切都可以这样完成:

ALTER PROCEDURE [dbo].[usp_specificorderchangedhistory]
    @startRowIndex int,
    @maximumRows int, 
    @OrderDate datetime= null   
AS
BEGIN

    DECLARE @first int,
            @last int

    SET @first = @startRowIndex * @maximumRows
    SET @last = (@startRowIndex * @maximumRows) + @maximumRows

    SELECT * 
    FROM (
        SELECT  ROW_NUMBER() OVER (ORDER BY so.OrderID DESC) AS [Row], 
                so.OrderID,
                u1.Firstname+' '+u1.Lastname as [Username],
                U.Firstname as CustomerName,
                so.OrderNumber,
                so.TotalAmount,
                so.Status,
                so.OrderDate,
                so.Comment,
                p.PaymentMode as PaymentMethod,
                p.PaymentMethod as Payment_Mode,
                p.IsPaid
        FROM SpecificOrders AS so
        INNER join Users as U 
            on so.UserID = U.UserID
        INNER join Users as u1 
            on so.CreatedBy = u1.UserID       
        INNER join SpecificOrderPayment as p 
            on so.OrderID= p.OrderID  
                and so.OrderDate = @OrderDate
    ) spec
    WHERE [Row]>@first  AND [Row]<=@last

    SELECT count(*) 
    FROM (

        SELECT ROW_NUMBER() OVER (ORDER BY so.OrderID DESC) AS [Row]
        FROM SpecificOrders AS so
        INNER join Users as U 
            on so.UserID = U.UserID
        INNER join Users as u1 
            on so.CreatedBy = u1.UserID   
        INNER join SpecificOrderPayment as p 
            on so.OrderID= p.OrderID 
                and so.OrderDate = @OrderDate
    ) spec

end

【讨论】:

  • 将 varchar 值 '09/29/2016' 转换为数据类型 int 时出现同样的错误转换失败。另外,我执行为 usp_specificorderchangedhistory '08/20/2016' 并且错误中的日期正在占用日期不同
  • 我在其他查询中使用上面的@cond,它被打印出来,但在其他查询中使用时不会被执行
  • 你发布了你所有的SP?对我来说它运行良好。
  • 你怎么用的,请发帖。
  • @gofr 你不需要转换!只需and so.OrderDate = @OrderDate 就足够了。要使转换生效,BOTH 列和参数必须为 datetime。那为什么要转换呢?
猜你喜欢
  • 2011-12-01
  • 2012-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多