Need advice to prevent Insert

  • I've table as follows,

    CREATE TABLE [dbo].[roomBooked](

    [idx] [int] IDENTITY(1,1) NOT NULL,

    [roomno] [varchar](50) NOT NULL,

    [useStrDte] [datetime] NOT NULL,

    [useEndDte] [datetime] NOT NULL,

    [dtVersion] [timestamp] NOT NULL,

    CONSTRAINT [PK_roomBooked] PRIMARY KEY CLUSTERED

    (

    [idx] ASC

    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

    ) ON [PRIMARY]

    Above table storing booking room no, Start Date Used, and End Date Used.

    My scenario as follow,

    1. If roomno='2A', useStrDte=2 May 2010, and useEndDte=7 May 2010, insert statement as follow

    insert into roomBooked(roomno,useStrDte,useEndDte) values('2A','5/2/2010','5/7/2010');

    2. Let's say, there's another transaction trying to execute as follow

    insert into roomBooked(roomno,useStrDte,useEndDte) values('2A','5/6/2010','5/9/2010');. The fact is, this T-SQL have to be prevented because of roomno='2A' is booked from 2 May 2010 till 7 May 2010.

    My question is,

    1. How T-SQL look's like to prevent insert into roomBooked(roomno,useStrDte,useEndDte) values('2A','5/6/2010','5/9/2010'); to be inserted.

  • You could use a unique index or constraint.

    Converting oxygen into carbon dioxide, since 1955.
  • awesome that you posted the table structure and sample data; it made my creation of a possible solution and testing so easy. thank you!!!

    The only way i see is you have to check all the dates between the current bookings; to do that, you need some sort of a Calendar table.

    note i changed the way the insert occurs in my example. I hope it's obvious you'd parameterize the three values.

    this example seems to work just as you'd expect; here's the PRINT results:

    no overlap, proceed with insert

    (1 row(s) affected)

    Raise An Error, date overlap.

    and here's the code with a calendar table:

    --drop table TallyCalendar

    IF object_id('TallyCalendar') IS NOT NULL

    DROP Table dbo.TallyCalendar

    GO

    CREATE TABLE dbo.TallyCalendar (

    TheDate datetime not null primary key,

    [DayOfWeek] varchar(50),

    IsHoliday bit default 0,

    IsWorkHoliday bit default 0,

    HolidayName varchar(100) )

    CREATE NONCLUSTERED INDEX [IX_TallyCalendar]

    ON [dbo].[TallyCalendar] ([DayOfWeek],[TheDate])

    INCLUDE ([IsHoliday],[IsWorkHoliday],[HolidayName])

    Declare @NumberOfYears int

    SET @NumberOfYears = 50 --x years before and after todays date:

    ;WITH TallyNumbers AS

    (

    SELECT dateadd( dd,(-365 * @NumberOfYears) + RW ,DATEADD(dd, DATEDIFF(dd,0,getdate()), 0)) As N

    FROM (

    SELECT TOP (730 * @NumberOfYears)

    row_number() OVER (ORDER BY sc1.id) AS RW

    FROM Master.dbo.SysColumns sc1

    CROSS JOIN Master.dbo.SysColumns sc2

    ) X

    )

    INSERT INTO dbo.TallyCalendar(TheDate,[DayOfWeek])

    SELECT

    TallyNumbers.N,

    datename(dw,TallyNumbers.N)

    FROM TallyNumbers

    CREATE TABLE [dbo].[roomBooked](

    [idx] [int] IDENTITY(1,1) NOT NULL,

    [roomno] [varchar](50) NOT NULL,

    [useStrDte] [datetime] NOT NULL,

    [useEndDte] [datetime] NOT NULL,

    [dtVersion] [timestamp] NOT NULL,

    CONSTRAINT [PK_roomBooked] PRIMARY KEY CLUSTERED

    (

    [idx] ASC

    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

    ) ON [PRIMARY]

    declare @room varchar(10),

    @st datetime,

    @et datetime

    SELECT @room = '2A',

    @st = '5/2/2010',

    @et = '5/7/2010'

    if exists(select

    roomBooked.*,

    TallyCalendar.TheDate

    from roomBooked

    inner join TallyCalendar on TallyCalendar.TheDate between roomBooked.useStrDte and roomBooked.useEndDte

    WHERE roomBooked.roomno = @room

    AND TallyCalendar.TheDate between @st and @et )

    begin

    PRINT 'Raise An Error, date overlap.'

    end

    else

    begin

    PRINT ' no overlap, proceed with insert'

    insert into roomBooked(roomno,useStrDte,useEndDte)

    SELECT @room,@st,@et

    end

    --next date to test:

    SELECT @room = '2A',

    @st = '5/6/2010',

    @et = '5/9/2010'

    if exists(select

    roomBooked.*,

    TallyCalendar.TheDate

    from roomBooked

    inner join TallyCalendar on TallyCalendar.TheDate between roomBooked.useStrDte and roomBooked.useEndDte

    WHERE roomBooked.roomno = @room

    AND TallyCalendar.TheDate between @st and @et )

    begin

    PRINT 'Raise An Error, date overlap.'

    end

    else

    begin

    PRINT ' no overlap, proceed with insert'

    insert into roomBooked(roomno,useStrDte,useEndDte)

    SELECT @room,@st,@et

    end

    Lowell


    --help us help you! If you post a question, make sure you include a CREATE TABLE... statement and INSERT INTO... statement into that table to give the volunteers here representative data. with your description of the problem, we can provide a tested, verifiable solution to your question! asking the question the right way gets you a tested answer the fastest way possible!

  • not sure how you handle checking in on hte same day someone else checks out; if i leave on 05/07/2009, someone else presumably could check in on the same date, right? you might need to tweak the logic just a bit to take that into consideration.

    Lowell


    --help us help you! If you post a question, make sure you include a CREATE TABLE... statement and INSERT INTO... statement into that table to give the volunteers here representative data. with your description of the problem, we can provide a tested, verifiable solution to your question! asking the question the right way gets you a tested answer the fastest way possible!

  • Hello Sir,

    tq very much. your guidance is my inspiration

Viewing 5 posts - 1 through 4 (of 4 total)

You must be logged in to reply to this topic. Login to reply