9

我正在做一个酒店项目,我需要检查房间的可用性。这里的逻辑是首先需要检查房间是否可用,然后我需要检查客户输入的结帐日期是否等于任何客户的结帐日期:

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 

但我收到一个错误:

消息 4145,级别 15,状态 1
在“开始”附近的预期条件的上下文中指定的非布尔类型的表达式。

4

2 回答 2

8

问题实际上就在这里,您只需说IF (get result)

ELSE IF(SELECT *
             FROM   Customerdetail
             WHERE  RoomType = @RoomType
                    AND CheckOut = @CheckOut)

我认为这应该是IF (get result) = somethingor 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 )

如所写,如果返回多于一行,它将产生:

消息 512,级别 16,状态 1,第 1 行
子查询返回超过 1 个值。当子查询跟随 =、!=、<、<=、>、>= 或子查询用作表达式时,这是不允许的。

因此,您应该EXISTS按照他的建议进行编码。

正如 Martin 在评论中建议的那样,您还应该确保在高并发性下测试此解决方案。

于 2013-09-10T15:39:22.070 回答
2

改变:

IF ( (SELECT Available
            FROM   rooms
            WHERE  roomtype = @RoomType) > 0 )

到:

IF ( exists(SELECT Available
            FROM   rooms
            WHERE  roomtype = @RoomType) )
于 2013-09-10T15:33:47.457 回答