我应该用sql请求检查是否存在外键,还是应该尝试插入并捕获它是否失败?
我可以检查我引用的密钥是否存在。
我的问题更多的是理论上的:抓住异常与每次插入一次查询db。
例如说你有两张桌子,猫和人。 Cats有一个引用Human的外键。在我尝试插入猫之前,我应该检查是否存在具有给定猫主人列的人,或者我应该尝试盲目插入并捕获它是否失败。
答案 0 :(得分:2)
这不是一个简单的答案,它实际上取决于您的应用程序要求。
虽然作为一般经验法则,您应该避免将异常作为正常应用程序流的一部分进行计数,并且使用异常会有一些问题。
首先,当您收到SQL Exception时,您需要确定异常来源,这可能很复杂并且特定于数据库(有关详细信息,请参阅此处:How to catch a specific exception in JDBC?)
其次,即使您设法将例外代码限制为参照完整性,您仍然会面临Cat
问题来源的问题。引用Human
及其最喜欢的Food
。
此外,即使您设法确定错误来源是缺少参照完整性,也可能有一些原因(因此,而不是简单地插入新行,您需要进行一些额外的调查)。想象一下,你想为'多萝西史密斯'插入一只猫,而你正试图这样做多萝西结婚了(很可能这只猫是恶毒婆婆的结婚礼物;并将她的名字改为'Dorothy Griffith'。所以现在当你尝试插入猫时,如果你只是盲目地插入一条新记录,你就会在你的数据库中复制多萝西。
此外,由于上述原因,使用人工创建的外键(而不是一组唯一标识用户的字段)是有意义的。在这种情况下,您需要首先获取此内部标识(如果您不希望应用程序知道标识符,使用存储过程和使用ORM框架(如Hibernate),有几种方法可以解决此问题。最常见的一个)。
话虽如此,我仍然可以想象处理异常会带来好处的情况,主要是当您需要满足特定的性能要求时。这种情况的例子可以是一个交易系统,在那里你可以获得货币和快速的汇率。由于引入新货币很少发生,因此它可以被视为一种特殊情况,检查它是否存在是没有意义的(尽管在正确设计的系统中,这只会使您无法调用哈希值用于检查货币是否存在的函数,因为您可以在内部缓存所有货币,这实际上可能比使用try ... catch ...
块包装db调用更快。
总而言之,尽量不要使用异常,而是通过正确定义应用程序逻辑解决问题,如果真的需要,可以回到使用异常。
答案 1 :(得分:0)
该段落出现在问题中
即,例如,假设您有两个表格,猫和人。猫具有引用人的外键。在尝试插入Cat之前,应该检查是否存在具有指定cat所有者列的人,还是应该盲目插入并捕获失败的人。
这里提到CAT具有引用HUMAN的外键。
因此,无需检查HUMAN是否具有要作为外键插入到CAT表中的键(记录)。
因为数据库抛出
完整性约束(FK_T_NAME)已违反-未找到父键异常
假设您使用的是Oracle DB,那么它将引发以下异常
ORA-02291:违反完整性约束-未找到父密钥
因此,每当您收到此异常时,这意味着您要作为外键插入到CAT表中的值在HUMAN表中不存在。
与我使用JDBC测试的结果相同,它给出以下错误
由以下原因引起: java.sql.SQLIntegrityConstraintViolationException :ORA-02291:违反完整性约束(FK_T_NAME)-未找到父键