我正在开展酒店项目,我需要检查房间的可用性。这里的逻辑首先需要检查房间可用性,如果它不可用,那么我需要检查客户输入的结账日期是否等于任何客户的结账日期:
ALTER PROCEDURE [dbo].[customerdetails] (@CheckIn DATE, ...)
AS
BEGIN
BEGIN TRY
IF ( (SELECT Available
FROM rooms
WHERE roomtype = @RoomType) > 0 )
BEGIN
INSERT INTO Customerdetail
VALUES (@CheckIn, ...)
END
ELSE IF(SELECT *
FROM Customerdetail
WHERE RoomType = @RoomType
AND CheckOut = @CheckOut)
BEGIN
INSERT INTO Customerdetail
VALUES (@CheckIn, ...)
END
END TRY
BEGIN CATCH
DECLARE @ErrMessage NVARCHAR(max)
SET @ErrMessage=ERROR_MESSAGE()
RAISERROR (@ErrMessage,16,1)
END CATCH
END
但是我收到了一个错误:
Msg 4145,Level 15,State 1
在“BEGIN”附近的预期条件的上下文中指定的非布尔类型的表达式。
答案 0 :(得分:8)
问题实际上就在这里,您只需说IF (get result)
:
ELSE IF(SELECT *
FROM Customerdetail
WHERE RoomType = @RoomType
AND CheckOut = @CheckOut)
我认为这应该是IF (get result) = something
或IF something (about result)
,例如:
ELSE IF EXISTS (SELECT *
FROM Customerdetail
WHERE RoomType = @RoomType
AND CheckOut = @CheckOut)
保罗认为这条款不合适是正确的:
IF ( (SELECT Available
FROM rooms
WHERE roomtype = @RoomType) > 0 )
如上所述,如果返回多行,则会产生:
Msg 512,Level 16,State 1,Line 1
子查询返回的值超过1。当子查询遵循=,!=,<,< =,>,> =或子查询用作表达式时,不允许这样做。
因此,您应该按照他的建议使用EXISTS
对此进行编码。
正如Martin在评论中所建议的那样,您还应确保在高并发性下测试此解决方案。
答案 1 :(得分:2)
变化:
IF ( (SELECT Available
FROM rooms
WHERE roomtype = @RoomType) > 0 )
为:
IF ( exists(SELECT Available
FROM rooms
WHERE roomtype = @RoomType) )