Sql 防止更新到不存在的行

Sql 防止更新到不存在的行,sql,oracle,oracle11g,Sql,Oracle,Oracle11g,在工作中,我们有一个表来保存设置,该表基本上包含以下列: PARAMNAME 值 大多数情况下会添加新设置,但很少会删除设置。不幸的是,这意味着,尽管更新会导致“0行更新””并导致意外行为,但之前可能已更新此值的任何脚本将继续这样做 这种情况是最近一次回归测试失败后发现的,但只是在对系统中数据不同的原因进行了大量调查之后 因此,我的问题是:当更新导致零行更新时,是否有方法生成错误条件? 以下是我想到的一些选择,但没有一个是真正理想的: PL/SQL包装器,它注意到更新失败并引发异常。 不

在工作中,我们有一个表来保存设置,该表基本上包含以下列:

  • PARAMNAME
大多数情况下会添加新设置,但很少会删除设置。不幸的是,这意味着,尽管更新会导致“
0行更新”
”并导致意外行为,但之前可能已更新此值的任何脚本将继续这样做

这种情况是最近一次回归测试失败后发现的,但只是在对系统中数据不同的原因进行了大量调查之后

因此,我的问题是:当更新导致零行更新时,是否有方法生成错误条件?

以下是我想到的一些选择,但没有一个是真正理想的:

  • PL/SQL包装器,它注意到更新失败并引发异常。
    • 不理想,因为它不会阻止任何人/脚本手动执行更新
  • 表上引发异常的触发器。
    • 与我们目前逐步淘汰触发器的政策背道而驰
    • 需要在每次删除设置时更新触发器,并维护过时设置列表(如果执行排除)
    • 可能在更改表时遇到问题(如果通过查询当前存在的设置来执行包含操作)

    • 这不是一个真正的解决方案,而是一种稍微组织事情的方法:

      使用参数定义创建一个单独的表,并从参数值表链接到该表。需要引用参数定义(不允许为空)

      定义表
      参数(ID、名称)

      实际设置表
      参数值(参数ID,值)


      (更改表结构也是在未更新的脚本中引发错误的一种非常有效的方法…

      对我来说,PL/SQL包装器似乎是最好的选择。除了生成序列和插入历史记录之外,触发器是逐步淘汰的好方法


      如果您担心有人手动更新而不是使用PL/SQL包装器,只需限制用户角色,使其对表没有更新权限,但对过程有执行权限。

      可能是因为您可以使用MERGE语句 这里有一个链接

      merge语句允许您在同一查询中组合insert和update,因此,如果所需的行不存在,您可以在缓冲区表中插入一条记录,以指示该行不存在,或者您可以更新所需的记录


      希望这能有所帮助

      0行的更新如何导致数据不同的情况?@所讨论的所有设置都是时间延迟。在旧代码中,值被更新,数据包括给定的延迟。在新的代码中,它不是。Ergo回归。如果设置控制某些功能是否打开,则会发生完全相同的情况。好主意,但这与普通更新一样存在问题,因为它需要有人注意缓冲区表中有新记录。如果他们可以注意到这一点,那么他们也可以很容易地注意到0行已更新。但他们没有。我正在设法找出人为错误的可能性。