Database 过程内PL/SQL中的约束双重检查

Database 过程内PL/SQL中的约束双重检查,database,oracle,plsql,Database,Oracle,Plsql,我需要一些关于我工作的DB的建议 我有了数据库,现在我正在研究过程、函数和触发器(PL/SQL)。有三个实体,其中两个从第三个实体继承(根据概念数据模型),这意味着有两个表引用第三个实体。我必须同时在“parent”表和“children”表中插入数据,因此我考虑创建一个插入到parent表中的过程,以及另一个插入到children表中的过程,它可以调用前一个过程 我的问题是,如果我尝试插入到父表,然后插入到子表,并且出于某种原因,我在子表中插入不满足约束的数据,会发生什么?换句话说,尽管有限制

我需要一些关于我工作的DB的建议

我有了数据库,现在我正在研究过程、函数和触发器(PL/SQL)。有三个实体,其中两个从第三个实体继承(根据概念数据模型),这意味着有两个表引用第三个实体。我必须同时在“parent”表和“children”表中插入数据,因此我考虑创建一个插入到parent表中的过程,以及另一个插入到children表中的过程,它可以调用前一个过程

我的问题是,如果我尝试插入到父表,然后插入到子表,并且出于某种原因,我在子表中插入不满足约束的数据,会发生什么?换句话说,尽管有限制,我是否仍必须验证函数中的输入数据?你有什么建议?

视情况而定

假设子表和父表之间存在外键约束,如果尝试使用父表中不存在的键在子表中插入行,
insert
将引发异常,指示违反了约束。如果您只是想让
INSERT
操作因约束冲突异常而失败,则无需检查任何内容

另一方面,您可能希望编写验证代码,以便为调用方提供更好的异常。例如,一个表通常会有多个外键引用其他各种表。检查参数是否有效可能是有益的,这样您可以更明确地告诉调用者哪个参数无效

如果您想知道如何确保父表和子表的插入都成功或都失败,那么您要讨论的是如何建立适当的事务边界。你会这样做的

BEGIN
  insert_into_parent( <<list of parameters>> );
  insert_into_child(  <<list of parameters>> );
  commit;
EXCEPTION
  WHEN others 
  THEN
    rollback;
    RAISE;
END;
开始
将_插入_父项();
将_插入_子项();
犯罪
例外情况
当别人
然后
回降;
提高;
结束;

请注意,PL/SQL应用程序始终必须显式提交或回滚。这些事务控制语句应该是尽可能高的级别。例如,您不希望在
insert\u-into\u-parent
过程中使用事务控制语句,因为如果您想要更广泛的事务范围,则永远无法使用该过程。

是的,存在外键约束,但这不是重点,而是表的其余约束。例如,假设我有这个表,它有一个特定的检查约束。如果我在第二个表中插入了数据(在第一个表中成功插入数据之后),并且由于某种原因它抛出了一个异常,因为它违反了约束,那么数据将记录在第一个表中,而不是第二个表中。这就是我所担心的。@user1231958-这就是事务边界的意义所在。如果对子表的插入失败,并且除非两个插入操作都成功,否则您不希望提交对子表的插入,则如果插入子表的过程引发异常,而不是发出提交,则应用程序只会发出回滚。我是否必须发出回滚指令,还是自动的?如果在一个过程中的一个表中有一个insert,然后从另一个过程调用它,我会怎么做?过程A->调用过程B->过程B插入并返回->过程A插入。此外。如果我从另一个过程调用了多个过程,我是否可以将它们分组到一个事务中,以便在出现问题时可以回滚?@user1231958-您可以而且应该有单独的过程。这些程序中不应包含交易控制语句。然后,您可以组装更高级别的过程,例如我发布的调用较低级别的过程并执行事务控制的过程。