April 27, 2007 at 6:43 am
Is this possible?
I have a database to record room bookings...
2 tables...
CREATE TABLE [tblBooking] (
[idBooking] [int] IDENTITY (1, 1) NOT NULL ,
[name] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[StartDate] [datetime] NOT NULL ,
[Length] [smallmoney] NOT NULL
) ON [PRIMARY]
GO
CREATE TABLE [tblDiary] (
[idDiary] [int] IDENTITY (1, 1) NOT NULL ,
[idBook] [int] NOT NULL ,
[dDate] [datetime] NOT NULL ,
)
GO
When a record is added into this tblBooking it adds corresponding rows into tblDiary, ignoring non-workdays.
At the moment a trigger takes the startdate and length from tblBooking and uses a function to return a table containing tblBooking.Length rows.
CREATE TRIGGER BookingAdded ON dbo.tblBooking FOR INSERT
AS
DECLARE @HID INT
DECLARE @LEN INT
DECLARE @SDDATETIME
SET @HID = (SELECT idBooking FROM INSERTED)
SET @LEN = (SELECT Length FROM INSERTED)
SET @SD = (SELECT StartDate FROM INSERTED)
INSERT INTO [Test].[dbo].[tblDiary]
( [idBook]
, [dDate])
SELECT @HID, DATE FROM fn_Calendar_GetArrayDates(@SD, @LEN)
This works fine for a single row insert but fails miserably on multi row inserts.
I can't get my head around how to join a function to the inserted table using an IN(?) clause. Is that even possible?
Colin
April 27, 2007 at 7:05 am
No you cannot use the function in that way.
Why not take the query from the function and join it to the INSERTED table?
What code is in the function?
Far away is close at hand in the images of elsewhere.
Anon.
April 27, 2007 at 7:11 am
Thanks for confirming that functions don't work that way
The function is
Create function fn_Calendar_GetArrayDates
(
@SDATE DATETIME,
@DURATION INT
)
RETURNS @DATES TABLE
(
DATE DATETIME
)
AS
BEGIN
DECLARE @EDATE DATETIME
SET @EDATE =
(SELECT c.Date
FROM FLITE_Calendar c
WHERE
c.WorkDay = 1
AND @duration = (
SELECT COUNT(*)
FROM FLITE_Calendar c2
WHERE c2.Date >= @Sdate
AND c2.Date <= c.Date
AND c2.WorkDay=1
)
)
INSERT @DATES ( DATE)
SELECT DATE
FROMFLITE_CALENDAR
WHEREDATE BETWEEN @SDATE AND @EDATE
ANDWorkDay=1
RETURN
END
April 27, 2007 at 7:55 am
You could leave the first part in the function and put the second in the join like this
CREATE FUNCTION dbo.fn_Calendar_GetEndDate (@SDATE DATETIME,@DURATION INT)
RETURNS datetime
AS
BEGIN
DECLARE @EDATE DATETIME
SELECT @EDATE = c.[Date]
FROM FLITE_Calendar c
WHERE c.WorkDay = 1
AND @DURATION = (SELECT COUNT(*)
FROM FLITE_Calendar c2
WHERE c2.DATE >= @SDATE
AND c2.[DATE] <= c.[DATE]
AND c2.WorkDay=1)
RETURN @EDATE
END
INSERT INTO [Test].[dbo].[tblDiary]
SELECT i.idBooking,c.[DATE]
FROM [INSERTED] i
INNER JOIN FLITE_CALENDAR c
ON c.[DATE] BETWEEN i.StartDate AND dbo.fn_Calendar_GetEndDate(i.StartDate,i.Length)
AND c.WorkDay = 1
I would be worried about performance though
Far away is close at hand in the images of elsewhere.
Anon.
April 27, 2007 at 8:15 am
This is quite a small system in fact and, apart from my bulk insert to import existing data, the likelyhood of their being bulk inserts is small.
Thanks for you help.
Colin
Viewing 5 posts - 1 through 4 (of 4 total)
You must be logged in to reply to this topic. Login to reply