Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将插入数据与SQL中的现有数据进行比较_Sql_Sql Server - Fatal编程技术网

将插入数据与SQL中的现有数据进行比较

将插入数据与SQL中的现有数据进行比较,sql,sql-server,Sql,Sql Server,这个标题可能会有误导性,我就是想不通 我有三张桌子;Employee、EmployeeSchedule和LocalStore。在Employee表中有一列名为“IsManager”的数据类型位,在EmployeeSchedule中,日期仅标记为“星期一”到“星期日”,并且每个商店都有一个唯一的StoreID: 我要实现的规则如下: 商店每天不能有超过1名经理 如果我试图在同一天向该存储添加另一个经理,我希望该表抛出一条错误消息 我在想这样的事情,我如何检查经理是否在同一天没有被分配到该商店 U

这个标题可能会有误导性,我就是想不通

我有三张桌子;Employee、EmployeeSchedule和LocalStore。在Employee表中有一列名为“IsManager”的数据类型位,在EmployeeSchedule中,日期仅标记为“星期一”到“星期日”,并且每个商店都有一个唯一的StoreID:

我要实现的规则如下:

商店每天不能有超过1名经理

如果我试图在同一天向该存储添加另一个经理,我希望该表抛出一条错误消息

我在想这样的事情,我如何检查经理是否在同一天没有被分配到该商店

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
是一周中的某一天(叙述表明是这样的)整数编码可能比任意的
日期
更合适。