【发布时间】:2010-08-17 08:03:02
【问题描述】:
我刚刚观察到一个奇怪的行为(当然甲骨文可能应该这样做,但它还不符合我的世界观):
我尝试在同一个事务中将两行插入父表和子表:
INSERT INTO V_Parent (ID, Name) VALUES (777, 'Hello World');
INSERT INTO T_Child (ParentID, Name) VALUES (777, 'Foo Bar');
子表有一个(ParentID) references Parent.ID 外键约束。
在第二条语句中,Oracle 失败并显示错误消息 “未找到父键。”
如果我禁用 FK 约束,它会起作用。我已经断言 ParentID 和 Parent.ID 匹配,并且我 100% 确定第一行在第二行之前成功执行。此外,我尝试提交每条语句,效果很好。
然而, 正如我的代码示例中的前缀所暗示的,第一个 INSERT 实际上是在父表的视图 上完成的。原因是我使用 NHibernate 并且映射使用背景中的视图(直到今天才引起任何问题)。
Q1:会不会是 Oracle 推迟了在视图上的插入操作,导致第二条语句失败?
Q2:我怎样才能最好地解决这个问题?
- 是否需要在视图上定义 INSTEAD OF 触发器?
- 我可以更改 VIEW 定义的设置吗?
- 我可以更改外键定义的设置吗?
- (我不得将休眠映射弯曲到原始表:这是使用视图的需求,因此可以将更改和/或安全问题隐藏在视图后面)
详细信息:C# WinForms 应用程序 - NHibernate - Oracle 10.2 - T_Child:迟早我也会为该表使用视图,它只是尚未定义。
编辑:根据 cmets 的更多详细信息:
-
ID 由 NHibernate 使用 Oracle 序列 (
<generator class="sequence">) 分配,并且在我的示例中是 INSERT 语句的一部分。我还验证了表格行中的结果 ID 与映射对象中保存的一个 NHibernate 匹配。 - 视图被定义为 JOINS 一些字段其他表的 SELECT。但是,在插入/更新时,我只更改属于主表(“T_PARENT”)的字段,这通常可以正常工作。
- 当前的外键约束是不可延迟,但这不应该有任何影响,因为父语句在子语句之前执行。 *)
*) 嗯...让我想想:既然我使用 NHibernate 会话来提交 SQL 查询,会不会是 NHibernate 以不同于我告诉它的顺序执行它们?
我会对此进行调查。 => 看来是这样,请参阅我自己的答案。
这是实际代码的样子:
ISession session = this.DAOFactory.NHibernateHelper.SessionFactory.OpenSession();
ITransaction tx = session.BeginTransaction();
try
{
// parent.ID == 0
session.SaveOrUpdate(parent);
// parent.ID == 777 (for example)
ISQLQuery query = session.CreateSQLQuery(
"INSERT INTO T_CHILD (PARENT_ID, NAME) VALUES (:parentId, :name)");
query.SetDecimal("parentId", parent.ID);
query.SetDecimal("name", "Foo Bar");
query.ExecuteUpdate(); // Fails with ORA-Exception
tx.Commit();
}
catch (Exception)
{
tx.Rollback();
throw;
}
finally
{
session.Close();
}
【问题讨论】:
-
子表可以先插入吗?你能检查一下吗?还可以查看可延迟约束(SET CONSTRAINT ...),它允许您以任何顺序插入数据并仅在事务结束时验证数据download.oracle.com/docs/cd/B10500_01/appdev.920/a96590/…
-
视图的定义是什么?它是否已经有一个 INSTEAD OF 触发器?
-
也许有一个触发器将您的 ID 777 替换为从序列中新生成的数字?
-
大家好,ID 是 NHibernate 从 oracle 序列 (
<generator class="sequence">) 生成的,并包含在 INSERT 语句中。数据库不会更改 ID(我验证了我可以在数据库中找到的 ID 与映射对象中找到的 ID 匹配。 -
数据库中没有触发器
标签: sql oracle oracle10g views foreign-keys