2013-05-12 43 views
3

我已經對不起...我很新的這整個張貼的東西,但我想我最好的...函數/存儲過程的兩個表之間插​​入根據病情

我有兩個表...'客戶'和'客房'...一個擁有UNIQUE CU_ID的客戶會留在一個房間(有一個UNIQUE ROOM_ID,不幸的是,對於我來說,有時候有兩個或三個CU_ID留在同一個房間...他們通常在同一天登記,所以CheckInDate應該是相同的...

當他們登記入住並在'客戶'表上輸入RoomNo時,我希望位域'已佔用'在「房間」表中設置爲「TRUE」。我用Trigger完成了這部分(見b elow)...

訣竅是當他們正在檢出...如果用戶手動標記該房間ID的「佔用」 - (位)字段爲「假」,那麼我想設置客戶表上的任何客戶在該時間段到達Getdate()的時間。

這裏是我的表,觸發器和一些測試數據:

CREATE TABLE [dbo].[Rooms](
[Room_ID] [int] IDENTITY(1,1) NOT NULL, 
[Room_No] [nvarchar](50) NULL, 
[Occupied] [bit] NULL, 
    [CheckInDate] [int] NULL, 

CONSTRAINT [PK_Rooms] PRIMARY KEY CLUSTERED 
(
[Room_ID] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

GO 

CREATE TABLE [dbo].[Customer](
[CU_ID] [int] IDENTITY(5000,1) NOT NULL, 
[CheckInDate] [datetime] NULL, 
[RoomNo] [int] NOT NULL, 
[Nights_Booked] [int] NULL, 
[DepartDate] [datetime] NULL, 
CONSTRAINT [PK_Customer] PRIMARY KEY CLUSTERED 
(
[CU_ID] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

GO 

ALTER TABLE [dbo].[Customer] WITH CHECK ADD CONSTRAINT [FK_Customer_Rooms] FOREIGN KEY([RoomNo]) 
REFERENCES [dbo].[Rooms] ([Room_ID]) 
GO 

ALTER TABLE [dbo].[Customer] CHECK CONSTRAINT [FK_Customer_Rooms] 
GO 

-- 2 Tables created including PK/FK Relationship 

這裏是我的第一步觸發...更新佔用爲True位列當ROOM_ID用於新入住:

Create TRIGGER [dbo].[Occupied] 
ON [dbo].[Customer] 
FOR INSERT 
NOT FOR REPLICATION 
AS 
BEGIN 
IF TRIGGER_NESTLEVEL() > 1 
RETURN 
UPDATE Rooms 
SET [Occupied] = 'True' 
FROM Rooms r 
JOIN Customer cu 
ON cu.[RoomNo] = r.[Room_ID] 
Join INSERTED INS 
ON cu.[RoomNo] = INS.[RoomNo] 
END 
GO 

我輸入一些測試數據到他們兩個......

SET IDENTITY_INSERT Rooms ON 

INSERT INTO Rooms 
(Room_ID, Room_No, Occupied) 
SELECT 1, 'A14', 0 UNION ALL 
SELECT 2, 'B2', 0 UNION ALL 
SELECT 3, 'C3', 0 UNION ALL 
SELECT 4, 'D8', 0 UNION ALL 
SELECT 5, 'K9', 0 

SET IDENTITY_INSERT Rooms OFF 

GO 

SET IDENTITY_INSERT Customer ON 

INSERT INTO Customer 
(CU_ID, CheckInDate, RoomNo, Nights_Booked, DepartDate) 
SELECT 5000, '2013-05-10', 1, 4, NULL UNION ALL 
SELECT 5001, '2013-05-10', 1, 4, NULL UNION ALL 
SELECT 5002, '2013-05-10', 2, 2, NULL UNION ALL 
SELECT 5003, '2013-05-10', 3, 3, NULL UNION ALL 
SELECT 5004, '2013-05-11', 4, 4, NULL UNION ALL 
SELECT 5005, '2013-05-11', 4, 4, NULL UNION ALL 
SELECT 5006, '2013-05-11', 4, 4, NULL 

SET IDENTITY_INSERT Customer OFF 

-- Test Data entered in rows on 'Rooms' and 'Customer'-Tables 

的觸發作品沒問題,它會使用相同的Room_ID更新所有記錄(客戶表中分別爲RoomNo)。

我試圖解決與其他觸發器的問題。而且如果我將這一個傳遞給Room-Table,我將根據特定客戶的Check-In-Date來獲取SQL Server輸入的起飛日期。不幸的是,它只更新了客房表上特定Room_ID的第一條條目的數據......並且在兩個表格之間來回傳遞似乎非常笨拙。我想我需要一個存儲過程/函數真正實現這一目標:

  • 在客戶記錄的插入通NEWEST CheckInDate並插入到房間表字段CheckInDate
  • 當Rooms.Occupied被標記爲「假」,設置退房,日期與Customer.RoomNo = Rooms.Room_ID AND Customer.CheckInDate = Rooms.CheckInDate所有CU_ID到GETDATE()...

我與第一部分掙扎 - 如何通過Insert上的CheckInDate,如果某個值存在,則用更新的日期更新它...

不知道,再次...我都是新的:)

感謝您的任何幫助提前!

+1

觸發器是一個難以維繫的混亂。編寫一個前端,用單獨的查詢更新用戶和房間表。 (好的問題,我已經投了票,也許沒有觸發恐懼症的人會回答:)) – Andomar 2013-05-12 19:04:52

+0

歡呼的回覆:)前端不是一個選項(第三方) - 觸發器是一個混亂 - 簡單的在這種情況下,只需將插入位上的位字段更改爲True即可 - 但這就是爲什麼我正在尋找更多有關存儲過程/函數的想法以獲得我想要的內容 - 任何想法都可以使用 - 感謝您的投票;) – user2312782 2013-05-12 19:30:45

回答

0

歡迎來到StackOverflow。在將來,如果你保持簡短的例子,這將對我們非常有幫助。例如,在這種情況下,我們所需要的只是每個表中的幾列(沒有任何選項/約束)。

您不應該手動更新位。改用存儲過程。

CREATE PROCEDURE [dbo].[usp_CheckoutRoom] (
    @RoomID 
) 
AS 
    UPDATE [dbo].[Rooms] 
    SET [Occupied] = 0 
    WHERE [Room_ID] = @RoomID 

    UPDATE [dbo].[Customer] 
    SET [DepartDate] = GETDATE() 
    WHERE [RoomNo] = @RoomID 
END 

我假設你還在設計你的系統,但是如果一個客戶簽出多個房間會發生什麼?您需要客戶/房間交叉參考表。

[dbo].[Customer] 
[dbo].[Room] 
[dbo].[CustomerRoom] 

另外請注意,這不是很明顯,[DBO]。[客戶] [RoomNo]其實就是[RoomID。

+0

Hi J Lo, 很抱歉,對於這篇長文章,我將在未來保持較短,只是被告知要儘可能多地寫入信息......正如我所說,這篇文章對我來說是新的:) 更新位字段由最終用戶通過.asp-Application完成,以便修復。我們有三張桌子,但我們的業務邏輯工作不同,所以[客戶房間]是不必要的,因爲客戶得到房間分配,所以它不像酒店預訂......謝謝你們 – user2312782 2013-05-14 11:46:16