这是一个 SQL 专家的问题。我正在使用 SQL Server 2008 R2
我有两个相关的表:Labs
和LabUsers
.
用户被分配到实验室,没有任何顺序的整个组的重复。
目标是插入一个@userName
(例如@user = "Paul"
)来LabUsers
满足以下所有限制:
不超过
@maxUsers
一个组(例如@maxUsers=4
)没有完整组的重复(完整实验室)。组中用户的顺序并不重要。[编辑]
如果不允许现有实验室,则创建 (
INSERT
) 一个新实验室,然后插入 的行@user
,不超过@maxLabs
(例如@maxLabs=5
)。非常重要:一秒钟内有许多来自服务器的并发相同请求,这可能会相互干扰。因此,该命令一开始执行,就不允许执行其他查询,直到该命令结束。
如果不能满足上述限制,查询应返回 0,并返回
LabID
插入行的 。[编辑]有几个实验室的区域。区域是独立的。每个区域 #labCount 由
@maxLabs
. 所有区域的@maxLabs
都相等,因此Total_maxLabs
=@maxLabs
x#zonesCount
。例如@zone=51
(稍后@zone=52, 53 etc.
)。(相同的 LabUser 可以不受限制地使用区域。区域之间不“了解”彼此)LabID
inLabUsers
是来自 的外键Labs
。
这个例子:
这是Labs
表格:
LabID LabName LabZone
----- ------- -------
1 North 51
2 North East 51
3 South West 51
而且LabUsers
是:
LabUserID LabUserName LabID
--------- ----------- -----
1 Diana 3
2 Julia 2
3 Paula 2
4 Romeo 1
5 Julia 3
6 Rose 2
7 Diana 1
8 Diana 2
9 Julia 1
10 Romeo 3
11 Paul 1
在示例中,用户的分配方式如下:
LabID LabName LabZone LabUsers (ordered LTR a>z)
----- ------- ------- --------
1 North 51 Diana•Julia•Paul•Romeo
2 North East 51 Diana•Julia•Paula•Rose
3 South West 51 Diana•Julia•Romeo
- 插入不应是 into
LabID=1
或 2,因为这些实验室中已经有 4 个用户。 - 由于
LabID=3
使用LabID=1
.
因此,因为@maxLabs
不是 3(现有实验室),所以需要插入一个新行Labs
,其值为LabZone=@zone=51
。
IDENTITY
将为新行设置4 LabID
。
现在是插入新实验室的Paul
时候了LabUsers
。LabID
如何解决这个问题呢?
使用什么方法来确保命令作为一个整体执行而不受干扰?
创建数据库的脚本是:
CREATE DATABASE [Allocation]
GO
USE [Allocation]
GO
CREATE TABLE [dbo].[LabUsers](
[LabUserID] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED ,
[LabUserName] [nvarchar](50) NOT NULL,
[LabID] [int] NOT NULL)
GO
SET IDENTITY_INSERT [dbo].[LabUsers] ON
INSERT [dbo].[LabUsers] ([LabUserID], [LabUserName], [LabID]) VALUES (1, N'Diana', 3)
INSERT [dbo].[LabUsers] ([LabUserID], [LabUserName], [LabID]) VALUES (2, N'Julia', 2)
INSERT [dbo].[LabUsers] ([LabUserID], [LabUserName], [LabID]) VALUES (3, N'Paula', 2)
INSERT [dbo].[LabUsers] ([LabUserID], [LabUserName], [LabID]) VALUES (4, N'Romeo', 1)
INSERT [dbo].[LabUsers] ([LabUserID], [LabUserName], [LabID]) VALUES (5, N'Julia', 3)
INSERT [dbo].[LabUsers] ([LabUserID], [LabUserName], [LabID]) VALUES (6, N'Rose', 2)
INSERT [dbo].[LabUsers] ([LabUserID], [LabUserName], [LabID]) VALUES (7, N'Diana', 1)
INSERT [dbo].[LabUsers] ([LabUserID], [LabUserName], [LabID]) VALUES (8, N'Diana', 2)
INSERT [dbo].[LabUsers] ([LabUserID], [LabUserName], [LabID]) VALUES (9, N'Julia', 1)
INSERT [dbo].[LabUsers] ([LabUserID], [LabUserName], [LabID]) VALUES (10, N'Romeo', 3)
INSERT [dbo].[LabUsers] ([LabUserID], [LabUserName], [LabID]) VALUES (11, N'Paul', 1)
SET IDENTITY_INSERT [dbo].[LabUsers] OFF
CREATE TABLE [dbo].[Labs](
[LabID] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED ,
[LabName] [nvarchar](50) NULL,
[LabZone] [int] NOT NULL)
GO
SET IDENTITY_INSERT [dbo].[Labs] ON
INSERT [dbo].[Labs] ([LabID], [LabName], [LabZone]) VALUES (1, N'North', 51)
INSERT [dbo].[Labs] ([LabID], [LabName], [LabZone]) VALUES (2, N'North East', 51)
INSERT [dbo].[Labs] ([LabID], [LabName], [LabZone]) VALUES (3, N'South West', 51)
SET IDENTITY_INSERT [dbo].[Labs] OFF