在预期条件的上下文中指定的非布尔类型的表达式,靠近'Begin'

use*_*331 9 sql sql-server

我正在做一个酒店项目,我需要检查房间的可用性.这里的逻辑首先需要检查房间可用性,如果它不可用,那么我需要检查客户输入的结账日期是否等于任何客户的结账日期:

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 
Run Code Online (Sandbox Code Playgroud)

但是我收到一个错误:

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

Aar*_*and 8

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

ELSE IF(SELECT *
             FROM   Customerdetail
             WHERE  RoomType = @RoomType
                    AND CheckOut = @CheckOut)
Run Code Online (Sandbox Code Playgroud)

我想,这应该是,IF (get result) = something或者IF something (about result),例如:

ELSE IF EXISTS (SELECT *
             FROM   Customerdetail
             WHERE  RoomType = @RoomType
                    AND CheckOut = @CheckOut)
Run Code Online (Sandbox Code Playgroud)

保罗也是正确的,这条款不合适:

IF ( (SELECT Available
            FROM   rooms
            WHERE  roomtype = @RoomType) > 0 )
Run Code Online (Sandbox Code Playgroud)

如上所述,如果返回多行,则会产生:

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

所以,你应该使用它来编码 EXISTS按照他的建议.

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