【问题标题】:Oracle Unique Constraint Throwing Exception when rows do not exist行不存在时Oracle唯一约束抛出异常
【发布时间】:2019-12-20 21:32:18
【问题描述】:

我在 oracle 数据库中有一个表,我们称之为任务,我从批处理中插入一堆行。

我在 4 列上设置了唯一约束,其中一列可以为空(locationId、shelfId、itemId 和 batchId),其中一列可以为空(shelfId)

在解析 CSV 文件的值(从另一个数据库表中读取)的过程中,它们以 100 个为一组进行批处理,并发布到 API 以供进一步解析(转换为上述表的格式)并插入以供以后提交到另一个表(在不同的模式中,但具有相同的唯一约束)。我遇到的问题是文件中存在基于上述约束的重复项(它们通常是连续的,我只在文件中看到过一个附加条目)。 在它们被解析后,它们被插入,我看到唯一约束异常被抛出在 a) 没有在表中有一行和 b) 的行上不满足唯一约束。当我从初始导入文件中删除重复项时,我没有得到任何唯一约束异常(这......这很奇怪)。

我在 .net 中为 Oracle 数据库使用实体框架,我认为这与此无关,但从这个问题的怪异判断来看,它可能。我完全不知道该怎么做,我尝试编写额外的验证并在插入之前查找表中的记录,将它们从初始文件中删除(作为一种解决方法),但我不确定长期解决方案该怎么做。

示例数据:

LocationId ShelfId ItemID  BatchId 
1          NULL    00AXXFD 1 
1          NULL    00AXXFD 1 
1          NULL    00FFD12 1 
etc... 

【问题讨论】:

  • 即使您在唯一约束中有一个可空值,这仍然意味着您在列中只能有 1 个空值。你能给我们展示一个示例数据集吗?可能我理解错了
  • ``` LocationId ShelfId ItemID BatchId 1 NULL 00AXXFD 1 1 NULL 00AXXFD 1 1 NULL 00FFD12 1 等等... ``` 我看到的问题是第三行也将被视为重复,并抛出异常。数据集的第一行也没有被插入并引发异常。我已经向几位同事展示了这一点,他们也对此感到困惑。我开始怀疑这是某个地方的竞争条件,或者我正在使用的环境中正在运行另一个版本的服务,但这很奇怪。
  • 添加数据到问题,因为我没有想到没有格式化到 cmets...哈哈

标签: c# .net oracle entity-framework


【解决方案1】:

您收到英国错误,因为您的输入数据包含重复项。当您一次插入所有它们时,它们是同一事务的一部分,因此 Oracle 甚至在您提交之前就会看到重复项并引发异常。失败后,事务回滚,因此您看不到任何插入的记录,因此找不到重复项。

正确的方法是在插入之前从输入数据中删除重复项(正如您所做的那样)。 您使用 Oracle 通过在插入每一行后提交来强制执行 UK。

注意 - 正如我所说,您在插入每一行后可能不会提交。插入是一个一个发生还是一次全部发生并不重要,重要的是事务范围。 JDBC 有 autocommit=true/false 来启用单操作提交。如果为“真”,则在每次操作后提交事务。一般来说,它需要为“false”,以便您可以控制事务范围

【讨论】:

  • 记录插入是单独完成的(使用存储库模型,并且每次调用“插入”方法都会调用 SaveChanges(),所以我认为这不会是一个问题?虽然它不是一个异步调用...但是插入时不会提交每一行吗?
  • 正如我所说,您在插入每一行后可能不会提交。插入是一个一个发生还是一次全部发生并不重要,重要的是事务范围。
  • 啊啊啊好吧。是的,这现在更有意义了(Insert 方法接受正在插入的记录参数的列表,这使我假设事务范围仅用于该操作)。我已经更新了我调用它的方式,它现在似乎正在适当地插入记录。谢谢!
  • JDBC 有 autocommit=true/false 来启用单操作提交。如果为“真”,则在每次操作后提交事务。一般来说,它需要为“false”,以便您可以控制事务范围。
  • 我似乎在 dotnet 的配置中找不到自动提交配置,是在数据库服务器上配置的,还是在请求/应用程序级别配置的?
猜你喜欢
  • 2011-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多