将插入数据与SQL中的现有数据进行比较
这个标题可能会有误导性,我就是想不通 我有三张桌子;Employee、EmployeeSchedule和LocalStore。在Employee表中有一列名为“IsManager”的数据类型位,在EmployeeSchedule中,日期仅标记为“星期一”到“星期日”,并且每个商店都有一个唯一的StoreID: 我要实现的规则如下: 商店每天不能有超过1名经理 如果我试图在同一天向该存储添加另一个经理,我希望该表抛出一条错误消息 我在想这样的事情,我如何检查经理是否在同一天没有被分配到该商店将插入数据与SQL中的现有数据进行比较,sql,sql-server,Sql,Sql Server,这个标题可能会有误导性,我就是想不通 我有三张桌子;Employee、EmployeeSchedule和LocalStore。在Employee表中有一列名为“IsManager”的数据类型位,在EmployeeSchedule中,日期仅标记为“星期一”到“星期日”,并且每个商店都有一个唯一的StoreID: 我要实现的规则如下: 商店每天不能有超过1名经理 如果我试图在同一天向该存储添加另一个经理,我希望该表抛出一条错误消息 我在想这样的事情,我如何检查经理是否在同一天没有被分配到该商店 U
USE [StoreSystem]
GO
/****** Object: Trigger [dbo].[CheckManagerAndDay] Script Date: 2020-12-14 10:56:28 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[CheckManagerAndDay]
ON [dbo].[EmployeeSchedule]
AFTER INSERT, UPDATE
AS
BEGIN
SET NOCOUNT ON;
IF EXISTS (
SELECT *
FROM EmployeeSchedule
JOIN Employee ON Employee.ID = EmployeeID
JOIN LocalStore ON LocalStore.ID = StoreID
WHERE IsManager = 1 and StoreID = ?? and Day = ??
)
BEGIN
THROW 50000, 'Cannot have more than one manager on the same day.', 1;
END
END
我发现在SQLServer中实现这一点有点痛苦。为什么?因为SQL Server触发器是基于集合的。它们用于处理多行。这意味着副本可以以两种不同的方式出现:
- 存储中有一个现有的管理器,新数据将插入第二个管理器
- 没有现有的经理,但新数据有两个
isManager
标志冗余存储在EmployeeSchedule
中。然后,我们使用外键来确保它是正确的,并为您想要的属性创建唯一索引:
alter table Employee add constraint unq_isManager_id
unique (isManager, Id);
alter table EmployeeSchedule add constraint fk_employeeschedule_isManager_EmployeeId
foreign key (isManager, EmployeeId) references Employee(isManager, EmployeeId);
create unique index unq_employeeschedule_day_manager
on employeeschedule(day)
where isManager = 1;
然后是实现所需功能的唯一约束:
alter table Employee add constraint unq_isManager_id
unique (isManager, Id);
alter table EmployeeSchedule add constraint fk_employeeschedule_isManager_EmployeeId
foreign key (isManager, EmployeeId) references Employee(isManager, EmployeeId);
create unique index unq_employeeschedule_day_manager
on employeeschedule(day)
where isManager = 1;
瞧!没有触发器
您还应该修复数据模型,以便将
日期
存储为日期
而不是字符串。将日期/时间值存储为字符串是一个非常不好的习惯。我发现在SQL Server中实现这一点有点痛苦。为什么?因为SQL Server触发器是基于集合的。它们用于处理多行。这意味着副本可以以两种不同的方式出现:
- 存储中有一个现有的管理器,新数据将插入第二个管理器
- 没有现有的经理,但新数据有两个
isManager
标志冗余存储在EmployeeSchedule
中。然后,我们使用外键来确保它是正确的,并为您想要的属性创建唯一索引:
alter table Employee add constraint unq_isManager_id
unique (isManager, Id);
alter table EmployeeSchedule add constraint fk_employeeschedule_isManager_EmployeeId
foreign key (isManager, EmployeeId) references Employee(isManager, EmployeeId);
create unique index unq_employeeschedule_day_manager
on employeeschedule(day)
where isManager = 1;
然后是实现所需功能的唯一约束:
alter table Employee add constraint unq_isManager_id
unique (isManager, Id);
alter table EmployeeSchedule add constraint fk_employeeschedule_isManager_EmployeeId
foreign key (isManager, EmployeeId) references Employee(isManager, EmployeeId);
create unique index unq_employeeschedule_day_manager
on employeeschedule(day)
where isManager = 1;
瞧!没有触发器
您还应该修复数据模型,以便将
日期
存储为日期
而不是字符串。将日期/时间值存储为字符串是一个非常不好的习惯。您考虑在什么环境下运行您向我们展示的代码?特设SQL?存储过程?触发如果您能向我们展示更多的上下文,可能会更清楚(假设不是特别的)。除非推荐另一种方式,否则触发。您想在什么上下文中运行您向我们展示的代码?特设SQL?存储过程?触发如果你能向我们展示更多的上下文,可能会更清楚(假设不是特别的)。除非推荐另一种方式,否则触发。虽然如果Day
是一周中的某一天(叙述表明是这样),整数编码可能比任意的Day
更合适。尽管如果Day
是一周中的某一天(叙述表明是这样的)整数编码可能比任意的日期
更合适。