Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

An expression of non-boolean type specified in a context where a condition is expected, near 'Begin'

Tags:

sql

sql-server

I am working on a hotel project and I need to check the availability of rooms. Here the logic is first need to check the room availability if it is not available then I need to check if checkout date entered by the customer is equal to the checkout date of any customer:

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 

But I get an error:

Msg 4145, Level 15, State 1
An expression of non-boolean type specified in a context where a condition is expected, near 'BEGIN'.

like image 452
user2765331 Avatar asked Sep 10 '13 15:09

user2765331


People also ask

Is user a keyword in SQL?

User is a reserved keyword, so you must use square brackets to make it explicit that you mean the object named "User" it, i.e. use [User] instead of User .

Can we use contains in SQL?

CONTAINS is a predicate used in the WHERE clause of a Transact-SQL SELECT statement to perform SQL Server full-text search on full-text indexed columns containing character-based data types. CONTAINS can search for: A word or phrase. The prefix of a word or phrase.


2 Answers

The problem is actually here, where you just say IF (get result):

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

This should be, I think, either IF (get result) = something or IF something (about result), e.g.:

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

Also Paul is correct that this clause is not proper:

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

As written, if more than one row is returned, it will yield:

Msg 512, Level 16, State 1, Line 1
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.

So, you should code this using EXISTS as he suggested.

You should also make sure you test this solution under a high level of concurrency, as Martin suggested in a comment.

like image 63
Aaron Bertrand Avatar answered Oct 19 '22 21:10

Aaron Bertrand


Change:

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

to:

IF ( exists(SELECT Available
            FROM   rooms
            WHERE  roomtype = @RoomType) )
like image 27
paul Avatar answered Oct 19 '22 19:10

paul