Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.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_Oracle_Indexing_Constraints - Fatal编程技术网

Sql 我试图创建一个约束/索引,以提供列组合的最新记录和以前的记录

Sql 我试图创建一个约束/索引,以提供列组合的最新记录和以前的记录,sql,oracle,indexing,constraints,Sql,Oracle,Indexing,Constraints,我试着研究与我试图创造的内容密切相关的主题,但到目前为止,我没有任何运气。我正在尝试根据当前的_标志、id和当前的_年的组合创建一个约束/索引。id不是表的主键。只有1条当前标志、id和当前年的组合记录,其中当前标志='Y',可以有n条当前标志、id和当前年的组合记录,其中当前标志='n' current_flag='Y' ID=1 current_year=2013 current_flag='N' ID=1 current_year=2013 current_flag='N' ID=1

我试着研究与我试图创造的内容密切相关的主题,但到目前为止,我没有任何运气。我正在尝试根据当前的_标志、id和当前的_年的组合创建一个约束/索引。id不是表的主键。只有1条当前标志、id和当前年的组合记录,其中当前标志='Y',可以有n条当前标志、id和当前年的组合记录,其中当前标志='n'

current_flag='Y' ID=1 current_year=2013

current_flag='N' ID=1 current_year=2013

current_flag='N' ID=1 current_year=2013

current_flag='Y' ID=2 current_year=2013

current_flag='Y' ID=3 current_year=2013
逻辑是,如果在该ID、当前年份和当前标志='Y'下插入新记录(假设插入是新的当前记录)
根据ID和当前年份,上一条当前记录将被设置为当前\u flag='N'。

您可以在这三列上创建索引,而不会出现问题:

create index i_my_table on my_table(id, current_flag, current_year);
但是,您无法在单个表中约束此行为

然而,你有两种可能。如果要确保没有人可以通过插入数据来破坏您的条件,则可以执行以下操作:

  • 将当前表拆分为两个,一个是
    current\u flag='Y'
    TABLEY
    ),另一个是
    current\u flag='N'
    TABLEN

  • 表格
    上创建主键。这可以确保您保持自己的独特性

  • TABLEY
    上创建更新前触发器,将更新后的记录插入
    TABLEN

  • TABLEN
    上创建一个约束,确保标志只能是N。或者,您可以将此列完全删除,因为它的值在表中是已知的。这取决于您对具有数据库后端访问权限的人员的信任程度

  • 当需要在该标志为
    Y
    的位置插入新数据时,请使用合并:

    merge into tabley o
    using ( ... ) n
       on ( o.id = n.id
            and o.current_year = n.current_year )
     when matched then
          update ...
     when not matched then
          insert ...
    
    由于触发器的原因,每当您用新记录覆盖以前是Y的记录时,该记录将被放入
    表中。你的新纪录将保持不变

  • 为获得额外积分,创建一个物化视图,它是
    TABLEY
    TABLEN
    的联合体


  • 您可以创建一个索引,强制每个id和当前年份的唯一组合中只有一行的当前_标志值为“Y”:

    create unique index my_index
    on     my_table (
             case current_flag when 'Y' then ID           end,
             case current_flag when 'Y' then current_year end);
    
    从公式中可以看出,如果当前_标志不是“Y”,则索引中的条目为空,因此不包括在用于唯一性检查的索引中

    然而,这是一个有点黑客


    更好的解决方案是,在ID和当前年份的值上唯一的父表中包含一列,用于标识该行的该表主键,该行被视为该ID和当前年份的默认值。

    我同意双表解决方案是更好的方法。最初的问题闻起来像是一次拙劣的尝试,试图实现维护记录历史的要求;如果是这样,单独的日志表将是正确的解决方案。可能是这样,或者数据仓库正在缓慢地改变维度。