如何将日期参数传递给存储过程

时间:2014-12-18 03:07:03

标签: sql sql-server

我已经创建了一个存储过程,用于预订tblBooking表中没有作为参数传入的日期的房间。

Pdate的类型为varchar

当我尝试使用以下命令运行此存储过程时:

usr_sp_Search_Room_by_City_Date '','8','','DEC 13 2014'

抛出此错误:

  

Msg 102,Level 15,State 1,Line 10
  '%D%'。

附近的语法不正确

这是我的程序:

ALTER procedure usr_sp_Search_Room_by_City_Date 
    @RoomName varchar(100),
    @CityId int = 0,
    @LandMark varchar(100),
    @BookingDate varchar
as
begin
   Declare @Query as varchar(max)

   set @Query = 'Select * from tblUser tblusr 
                 join tblUserLogIn tblusrL on tblusr.UserId = tblusrL.UserId
                 join tblRoom tblP on tblP.RoomId = tblusr.UserId 
                 join tblImage tblImg on tblImg.RoomId = tblusr.UserId 
                 join tblCountry on tblP.RoomCountryId = tblCountry.CntryId 
                 join tblState on tblState.StateId = tblP.RoomStateId
                 join tblCity on tblCity.CityId = tblP.RoomCityId 
                 join tblRoomType on tblRoomType.RoomTypeId = tblP.RoomTypeId
                 where ''true''=tblImg.IsProfileImage and ''true''=tblusrL.Isconfirmed'

   if(@BookingDate != ' ')
      set @Query=@Query+'and tblP.RoomId not in (Select RoomId from tblBookings 

   where Pdate like ''%'+CAST(@BookingDate AS VARCHAR)+'%'''

   exec(@Query)

end 

4 个答案:

答案 0 :(得分:2)

如果你打印出查询,你可能会发现这样的事情:

where 'true'=tblImg.IsProfileImage and 'true'=tblusrL.Isconfirmedand tblP.RoomId not in (Select RoomId from tblBookings 

请注意,where语句会进入and,因为您没有间隔符。

您不打算进行比较'%D%',但这不是语法错误。这是因为您在varchar()声明中省略了长度。

以下是我的建议:

  • 始终使用长度varchar()
  • 如果要将日期传递到存储过程,请使用日期变量,而不是varchar()
  • 请勿将like与日期一起使用。
  • 通过打印@Query来调试此代码,以查看实际生成的内容。

答案 1 :(得分:0)

实际错误的来源是由于您需要在结尾处使用最后右括号:

AS VARCHAR)+'%'')'

此外,您需要set @Query=@Query+'and语句开头的空格。目前,SQL将呈现为(部分):

'true'=tblusrL.Isconfirmedand tblP.RoomId not

更好的是,您甚至不需要CAST,因为数据类型已经是VARCHAR,因此由IF控制的SET应为:

SET @Query = @Query + ' AND tblP.RoomId not in (Select RoomId from tblBookings 
  where Pdate like ''%'+ @BookingDate + '%'')';

始终为可变长度数据类型指定大小。 @BookingDate输入参数和CAST(@BookingDate AS VARCHAR)(同样应该删除)都应指定VARCHAR(20)。在某些情况下,VARCHAR / NVARCHAR / etc的默认大小为1.在其他情况下,它为30.在任何一种情况下,都不要依赖默认值。

一般说明:

  • Pdate字段中的实际数据是什么样的?只是想知道为什么要使用LIKE代替=进行测试。

  • 您应该使用BITIsProfileImage的{​​{1}}数据类型,或至少Isconfirmed。任何一个都比字符串字段更有效率。

答案 2 :(得分:0)

不是约会日期。

这是动态查询的输出查询

Select * from tblUser tblusr 
join tblUserLogIn tblusrL on tblusr.UserId=tblusrL.UserId
join tblRoom tblP on tblP.RoomId=tblusr.UserId join tblImage tblImg 
on tblImg.RoomId=tblusr.UserId 
join tblCountry on tblP.RoomCountryId=tblCountry.CntryId join tblState 
on tblState.StateId=tblP.RoomStateId
join tblCity on tblCity.CityId=tblP.RoomCityId join tblRoomType 
on tblRoomType.RoomTypeId=tblP.RoomTypeId
where 'true'=tblImg.IsProfileImage and 'true'=tblusrL.Isconfirmedand tblP.RoomId not in (Select RoomId from tblBookings 

where Pdate like '%0%'

你最后错过了“)”。

where Pdate like ''%'+CAST(@BookingDate AS VARCHAR)+'%'')'

答案 3 :(得分:0)

如何传递日期参数?首先,将数据类型指定为date,而不是varchar。

其次,您不需要动态SQL。您可以为条件逻辑使用案例构造。具体来说,这个:

if(@BookingDate!=' ')
set @Query=@Query+'and tblP.RoomId not in (Select RoomId from tblBookings 
where Pdate like ''%'+CAST(@BookingDate AS VARCHAR)+'%'''

可以是这样的。

where @BookingDate is null
or 
(
@BookingDate is not null
and 
tblP.RoomId not in 
(Select RoomId from tblBookings 
where Pdate = @BookingDate)
)