繁体   English   中英

使用外键检查记录是否存在

[英]Checking record with a foreign key exists

我应该使用 sql 请求检查外键是否存在,还是应该尝试插入并捕获失败?

我可以检查我引用的密钥是否存在。

我的问题更像是一个理论问题:捕获异常与每次插入多查询一次数据库。

例如,假设您有两张桌子,Cats 和 Humans。 Cats 有一个引用 Human 的外键。 在我尝试插入 Cat 之前,我应该检查是否存在具有给定 cat 的所有者列的人,还是应该尝试盲目插入并在失败时捕获。

这不是一个简单的答案,它实际上取决于您的应用程序要求。

尽管作为一般经验法则,您应该避免将异常作为正常应用程序流程的一部分抛出,并且使用异常存在一些问题。

  • 首先,当收到 SQL 异常时,您需要确定异常的来源,这可能很复杂且特定于数据库(有关详细信息,请参见此处: 如何在 JDBC 中捕获特定异常?

  • 其次,即使您设法将异常代码限制为引用完整性代码,如果Cat既引用了Human又引用了它最喜欢的Food ,您仍将面临识别问题根源的任务。

  • 此外,即使您设法确定错误来源是缺少参照完整性,也可能有几个原因(因此,您需要进行一些额外的调查,而不是简单地插入新行)。 想象一下,您想为'Dorothy Smith'插入一只猫,而您正在尝试这样做时,Dorothy 结婚了(可能这只猫是来自恶意婆婆的结婚礼物;)并将她的名字更改为'多萝西格里菲斯' 因此,现在当您尝试插入 cat 时,如果您只是盲目地插入新记录,您将在数据库中复制 Dorothy。

  • 此外,由于上述原因,使用人为创建的 id 作为外键(而不是一组唯一标识用户的字段)是有意义的。 在这种情况下,您需要首先获得这个内部 id(如果您不希望应用程序知道标识符,有几种方法可以解决它,使用存储过程和使用 ORM 框架,例如 Hibernate 作为最常见的一种)。

话虽如此,我仍然可以想象处理异常会有其好处的情况,主要是当您需要解决特定的性能要求时。 这种情况的例子可以是一个交易系统,在该系统中,您拥有货币并为其提供快速的汇率。 由于引入新货币的情况很少发生,因此可以将其视为一种特殊情况,检查它是否存在没有意义(尽管在正确设计的系统中,这只会使您免于调用散列用于检查货币是否存在的函数,因为您肯定会在内部缓存所有货币,实际上这可能比用try ... catch ... block 包装 db 调用更快)。

因此,总而言之,尽量不要使用异常,而是通过正确定义应用程序逻辑来解决这个问题,如果确实需要,请回退到使用异常。

这一段出现在问题中

即例如说你有两张桌子,猫和人。 Cats 有一个引用 Human 的外键。 在我尝试插入 Cat 之前,我应该检查是否存在具有给定 cat 的所有者列的人,还是应该尝试盲目插入并在失败时捕获。

这里提到CAT有一个引用HUMAN的外键。

因此,无需检查 HUMAN 是否有您在 CAT 表中作为外键插入的键(记录)。

因为 DB 抛出

违反完整性约束 (FK_T_NAME) - 未找到父密钥异常

假设您使用的是 Oracle DB,那么它会抛出以下异常

ORA-02291: 违反完整性约束 - 未找到父密钥

因此,每当您遇到此异常时,这意味着您在 CAT 表中作为外键插入的值在 HUMAN 表中不存在。

同样我使用 JDBC 测试它给出以下错误

引起: java.sql.SQLIntegrityConstraintViolationException :ORA-02291:违反完整性约束(FK_T_NAME)-未找到父键

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM