【问题标题】:Oracle error when deferring constraint延迟约束时的Oracle错误
【发布时间】:2013-05-15 02:51:58
【问题描述】:

我正在尝试从查询日志中查找偶尔出现的错误:

SQLSTATE[HY000]: 一般错误: 1 OCIStmtExecute: ORA-00001: 违反唯一约束 (FOO.BAR)

这似乎发生在应用程序尝试在事务中执行以下查询时:

SET CONSTRAINT foo.bar DEFERRED

有问题的约束是使用以下 DDL 创建的:

ALTER TABLE baz
ADD CONSTRAINT bar
UNIQUE (quux, duux)
DEFERRABLE
INITIALLY IMMEDIATE
USING INDEX
TABLESPACE tuux

基本上,运行此查询的代码执行以下操作:

  • 开始交易
  • 推迟约束
  • 进行必要的更新
  • 取消延迟约束
  • 提交更新

我的问题是:上面的SET CONSTRAINT 查询怎么可能导致违反唯一约束?我确信这是有问题的查询,因为我有异常的堆栈跟踪。

【问题讨论】:

  • 我同意,在取消延迟约束之前,您不应该看到违反唯一约束的情况。请注意,set constraint x deferred 不是查询。我怀疑该约束是否真正可延迟,或者set constraint x deferred 语句中命名的约束是否正确。
  • 设置约束 x deferred 只有在更新后完成才会导致违规(因为我是 DDL 并且用于强制提交)。如果您只想调试数据,请尝试使用日志错误oracle-base.com/articles/10g/dml-error-logging-10gr2.php

标签: sql oracle constraints ddl unique-constraint


【解决方案1】:

来自(文档)[http://docs.oracle.com/cd/B19306_01/server.102/b14200/clauses002.htm]

DEFERRABLE 子句 DEFERRABLE 和 NOT DEFERRABLE 参数 指示在后续交易中是否有约束 检查可以推迟到使用 SET CONSTRAINT(S) 语句。如果省略此子句,则默认 不可延期。

您有一个唯一的密钥违规。

由于约束是可延迟的,因此只有在您执行 SET CONSTRAINT foo.bar DEFERRED 时才会进行验证。

【讨论】:

  • 你的建议对我的问题没有意义。我在进行任何更新之前发送SET CONSTRAINT ... DEFERRED。据我所知,在延迟约束之前不可能存在预先存在的唯一键违规,那么为什么验证会失败?我可以理解它是否在交易结束时失败,但不是开始......
  • 你是对的。在这种情况下,我会检查表上的约束是否定义为relynovalidate。也许该命令会触发某种隐式验证。
猜你喜欢
  • 2012-04-28
  • 2010-11-03
  • 2020-04-19
  • 1970-01-01
  • 2010-11-03
  • 2014-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多