5

也许这个问题已经被问过了,但我真的不知道如何搜索它:

我有 postgres 表“客户”,每个客户都有自己唯一的名称。为了实现这一点,我在此列中添加了唯一约束。

我用 php 访问表。

当用户现在尝试创建一个名称已被占用的新客户时,数据库会显示“Integrity Constraint Violation”,并且 php 会抛出一个错误。

我想要做的是在发生这种情况时在 html-input-field: "Customer-Name already taken" 中显示一个错误。

我的问题是我应该怎么做。

我应该捕获 PDO 异常,检查错误代码是否为“UNIQUE VIOLATION”,然后根据异常消息显示一条消息,还是应该在尝试插入之前使用附加语句检查重复名称新行?

什么是更好的做法?进行进一步的 sql 语句,或捕获和分析错误代码。

编辑: 我正在使用事务,并且我正在捕获任何异常以回滚。问题是,如果我应该过滤掉唯一违规,这样它们就不会导致回滚。

EDIT2: 如果我使用异常方法,我将不得不分析异常消息以确保唯一约束确实属于“名称”列。

这是我从异常中得到的一切:

["23505",7,"FEHLER: doppelter Schlüsselwert verletzt Unique-Constraint <customers_name_unique>\nDETAIL: Schlüssel <(name)=(test)> existiert bereits."]

获取有关该列的信息的唯一方法是检查“customers_name_unique”是否存在(它是唯一约束的名称)。

但是你也可以看到,消息是德语的,所以输出取决于系统/可能会改变。

4

5 回答 5

7

您应该捕获 PDO 异常。

让数据库失败比查找记录是否已经存在要快。

这也使应用程序“不太了解”数据库中的业务逻辑。当您告诉数据库唯一索引实际上是一个业务逻辑时,并且由于数据库正在处理该特定逻辑,因此最好在其他层(应用程序)中跳过相同的检查。

此外,当数据库层处理异常时,您可以避免竞争条件。如果您的应用程序正在检查一致性,那么您可能会冒另一个用户在第一个应用程序检查它是否可用后添加相同记录的风险。

于 2013-07-16T12:22:48.293 回答
2

这个问题并不真正属于这里,但我会回答你。

异常是发生异常情况的情况。这意味着您不应该使用它们来处理可能经常发生的情况。如果你这样做,那么它就像 GOTO 代码。更好的解决方案是预先检查是否有任何重复行。但是,带有异常的解决方案更容易,因此您需要决定是要使某些东西起作用,还是要按应有的方式编写某些东西。

于 2013-07-16T12:19:01.537 回答
1

我会捕捉到异常,因为(由于并发性)无论如何都可能发生,即使您事先检查了额外的查询。

于 2013-07-16T12:21:42.847 回答
0

在保存时检查是否存在(通过一个简单的字段,在您的情况下:约束列)。如果是肯定的 - 向用户显示有关重复的通知。但不要强迫数据库服务器返回异常。

于 2013-07-16T12:22:13.703 回答
0

错误很糟糕,我宁愿在添加之前检查名称是否不存在。那么您仍然应该检查插入时是否没有错误,以避免并发脚本尝试插入相同名称的情况(检查存在和插入之间有一点时间,因为它不是事务)。

于 2013-07-16T12:18:04.227 回答