Sql server 基于条件在两个表之间插入的函数/存储过程
我已经很抱歉了。。。我对这整个帖子都很陌生,但我正在尽我最大的努力 我有两张桌子……”“客户”和“房间”。。。一个拥有唯一CUU ID的单一客户住在一个房间里(拥有唯一的房间ID,对我来说很不幸,有时有2到3个CUU ID住在同一个房间里…他们通常在同一天入住,所以入住日期应该是相同的 当他们办理入住手续并在“客户”表中输入RoomNo时,我希望将“房间”表中的位字段“已占用”设置为“TRUE”。这部分我是通过触发器完成的(见下文) 诀窍是当他们签出时…如果用户手动将该房间ID的“已占用”-(位)字段标记为“FALSE”,那么我想在Customer表上为当前停留在该房间的任何客户设置DepartDate to Getdate() 以下是我的表、触发器和一些测试数据:Sql server 基于条件在两个表之间插入的函数/存储过程,sql-server,function,Sql Server,Function,我已经很抱歉了。。。我对这整个帖子都很陌生,但我正在尽我最大的努力 我有两张桌子……”“客户”和“房间”。。。一个拥有唯一CUU ID的单一客户住在一个房间里(拥有唯一的房间ID,对我来说很不幸,有时有2到3个CUU ID住在同一个房间里…他们通常在同一天入住,所以入住日期应该是相同的 当他们办理入住手续并在“客户”表中输入RoomNo时,我希望将“房间”表中的位字段“已占用”设置为“TRUE”。这部分我是通过触发器完成的(见下文) 诀窍是当他们签出时…如果用户手动将该房间ID的“已占用”-(位
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
这是我第一步的触发器…当房间ID用于新签入时,将占用的位列更新为True:
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(Customer表上的RoomNo)更新所有记录
我尝试用其他触发器来解决我的问题。如果我将该触发器传递到Room表,我会让SQL Server根据特定客户的入住日期输入出发日期。不幸的是,它只会使用Rooms表上针对该特定Room_ID的第一个条目来更新数据……而且看起来很尴尬地来回传递在这两个表之间。我想我需要一个存储过程/函数来真正实现这一点:
- 在插入客户记录时,通过最新的CheckInDate并将CheckInDate字段插入房间表
- 当Rooms.Occessed标记为“False”时,使用Customer.RoomNo=Rooms.Rooms\u ID和Customer.CheckInDate=Rooms.CheckInDate to GETDATE()设置所有CU\u ID的签出日期
谢谢你的帮助 欢迎来到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].[Customer].[RoomNo]实际上是[RoomID]这一点并不明显。触发器是无法维护的。编写一个前端,使用单独的查询更新用户和房间表。(这个问题很好,我投了赞成票,也许没有触发恐惧症的人会回答:)为答案干杯:)前端不是一个选项(第三方)-触发器一团糟-在本例中,简单的一个方法是在插入时将一个位字段更改为True,这是相当可维护的-这就是为什么我在寻找更多关于存储过程/函数的想法,以获得我想要的-任何想法都值得赞赏-感谢投票;)嗨,J罗,很抱歉发了这么长的帖子,我以后会把它缩短,只是被告知要在里面放尽可能多的信息。。。正如我所说的,这篇文章对我来说是全新的:)更新位字段是由最终用户通过.asp应用程序完成的,所以其中一个是修复的。我们有三张桌子,但我们的业务逻辑是不同的,所以[CustomerRom]是不必要的,因为客户得到了指定的房间,所以它不像是酒店预订。。。不管怎样,已经谢谢你了