Sql server 基于条件在两个表之间插入的函数/存储过程

Sql server 基于条件在两个表之间插入的函数/存储过程,sql-server,function,Sql Server,Function,我已经很抱歉了。。。我对这整个帖子都很陌生,但我正在尽我最大的努力 我有两张桌子……”“客户”和“房间”。。。一个拥有唯一CUU ID的单一客户住在一个房间里(拥有唯一的房间ID,对我来说很不幸,有时有2到3个CUU ID住在同一个房间里…他们通常在同一天入住,所以入住日期应该是相同的 当他们办理入住手续并在“客户”表中输入RoomNo时,我希望将“房间”表中的位字段“已占用”设置为“TRUE”。这部分我是通过触发器完成的(见下文) 诀窍是当他们签出时…如果用户手动将该房间ID的“已占用”-(位

我已经很抱歉了。。。我对这整个帖子都很陌生,但我正在尽我最大的努力

我有两张桌子……”“客户”和“房间”。。。一个拥有唯一CUU ID的单一客户住在一个房间里(拥有唯一的房间ID,对我来说很不幸,有时有2到3个CUU ID住在同一个房间里…他们通常在同一天入住,所以入住日期应该是相同的

当他们办理入住手续并在“客户”表中输入RoomNo时,我希望将“房间”表中的位字段“已占用”设置为“TRUE”。这部分我是通过触发器完成的(见下文)

诀窍是当他们签出时…如果用户手动将该房间ID的“已占用”-(位)字段标记为“FALSE”,那么我想在Customer表上为当前停留在该房间的任何客户设置DepartDate to 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
这是我第一步的触发器…当房间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的签出日期
我很难理解第一部分-如何在插入时通过CheckInDate,如果存在值,则使用较新的日期更新它

不知道,再说一遍……我都是新来的:)


谢谢你的帮助

欢迎来到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]是不必要的,因为客户得到了指定的房间,所以它不像是酒店预订。。。不管怎样,已经谢谢你了