sql - 在单行中创建表的实例?

标签 sql sql-server asp.net-mvc t-sql

当用户在 UI 中更新表时,我无法弄清楚如何创建表的快照(或实例)。

问题是:

我有一个用于“修正”的用户界面。在用户界面中,有一个“修正类型”下拉列表。修正类型也有自己的 UI,用户可以在此处选中/取消选中可用修正类型列表。当用户取消选中修订类型时,该类型将从所有修订的下拉列表中删除。客户要求对修订类型的更改仅影响新的修订,而不影响更改之前存在的修订。

因此,如果之前选中了“新建、草稿、已关闭”的修订类型值,并且未选中“草稿”,我仍然需要在 UI 中显示现有修订的所有三个值,然后仅新修正案显示"new"和“已关闭”。但随后,他们可以返回并重新打开“草稿”并再次显示该内容,但仅限于重新打开后创建的修正案。

对我来说,这意味着我需要为“修订类型历史记录”创建一个表。 “Amendment Type”表有一个 AmendmentTypeID 列,其中所有 ID 都显示为行。我会将它们显示为列,行由有效日期(值更改的日期)定义。然后,我会将修正案链接到 AmendmentTypeHistoryID,并通过查找 AmendmentTypeID 获取要显示的值。

例如

dbo.AmendmentType

AmendmentTypeID          Name         CreationDate       IsActive
      1                  New            6/2/2019            1
      2                  Draft          6/2/2019            1
      3                  Closed         6/2/2019            1

dbo.AmendmentTypeHistory

AmendmentTypeHistoryID     EffectiveDate     AmendmentTypeID     AmendmentTypeID     AmendmentTypeID
            1             6/3/2019           1 (New)             2 (Draft)               3 (Closed)

然后你改变它......

dbo.AmendmentType

AmendmentTypeID          Name         CreationDate       IsActive
      1                  New            6/2/2019            1
      3                  Closed         6/2/2019            1

dbo.AmendmentTypeHistory

AmendmentTypeHistoryID     EffectiveDate     AmendmentTypeID     AmendmentTypeID     AmendmentTypeID
            1             6/3/2019           1 (New)             2 (Draft)               3 (Closed)
            2             6/3/2019           1 (New)             3 (Closed)     NULL

总共有 77 种修改类型可能性。这不是我可以硬编码的东西,所以我希望我能以某种方式动态地完成它。

有谁知道我该怎么做?有没有更简单或更好的方法来完成我想做的事情?

最佳答案

这是一个非常困难且令人困惑的要求。如果 IsActive 的修订类型在您将其加载到下拉列表中和用户保存条目时不同,会发生什么情况?

忽略这一点,我会推荐一个表格,它将映射组合到有序的逗号分隔列表中。我的答案很少会打破范式,但否则就会很困难。

创建一个名为 AmendmentTypeGroup 的表:

create table AmendmentTypeGroup
(
AmendmentTypeGroupID int identity
,AmendmentTypes nvarchar(max) not null
,constraint PK_AmendmentTypeGroup primary key clustered(AmendmentTypeGroupID)
)

向您的修正案(非修正案类型)表添加一列:

alter table Amendmends add AmendmentTypeGroupID int null

每次在 Amendments 中插入一行时,请使用触发器或过程来确保首先将一组当时处于 IsActive 的所有 AmendmentTypes 的所有 ID 插入到 AmendmentTypeGroup 中,获取组 ID,然后插入包含您插入的组值的修订行。如果已经存在具有特定组合的组,只需获取其 ID 并使用它即可。

declare @amendmentCombination nvarchar(max)
declare @groupID int
select amendmentCombination=string_agg(convert(nvarchar(max),AmendmentTypeID),',') WITHIN GROUP ( ORDER BY AmendmentTypeID asc)
from AmendmentType
where IsActive = 1 -- will only work for sql server version 2017. Search XML path concatenation if you don't have it
select @groupID=AmendmentTypeGroupID
from AmendmentTypeGroup
where AmendmentTypes=@amendmentCombination
if @groupID is null
begin
    insert AmendmentTypeGroup(AmendmentTypes) select @amendmentCombination
    set @groupID=SCOPE_IDENTITY() -- last id entered
end

insert Amendments(..your_other_columns...,AmendmentTypeGroup)
    select ..your_other_columns...,@groupID

这样,对于每个 Amendment 行,您可以将其与 AmendmentTypeGroup 连接起来,以获取当时可用 AmendmentType 的逗号分隔列表。您必须将其拆分才能以表格形式呈现。

为了使您的数据更加稳健,您应该 1) 手动创建用于修订中现有行的所有 AmendmentTypeGroup,并将其 ID 插入 Amendment.AmendmentTypeGroup,以便您可以 2) 在 Amendment 上创建 FK .AmendmentTypeGroup 引用 AmendmentTypeGroup.AmendmentTypeGroupID 3) 在 AmendmentTypeGroup.AmendmentTypes 上创建唯一约束

如您所见,这很困难。小心行事。

关于sql - 在单行中创建表的实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56431979/

相关文章:

sql - 为什么 SQL Server 不推荐使用 SET ANSI_PADDING OFF?

c# - 如何在SQL中使用同一表联接名称?

sql-server - 您如何从 SQL Server 收集统计信息?

asp.net-mvc - 如何通过LINQ表达式从数据库中获取处于特定角色的所有应用程序用户的列表?

php - 我的数据库没有插入一些值

mysql - 如何加入 2 个表得到 1 个表?

java - SQLException错误

sql - 如何在sql server 2008中获取一周的第一天和一周的最后一天?

c# - 将 Grid.MVC 数据导出到 Excel

c# - 使用 AutoMapper 创建一个对象,该对象表示比较两个其他对象的结果