php - 使用 PHP PDO 处理失败的 UNIQUE 约束?

标签 php postgresql pdo

我正在使用 PostgreSQL 和 PHP(使用 PDO)构建一个简单的网络应用程序。我在一列上有一个 UNIQUE 约束,现在我正试图想出如何最好地处理将重复项插入该数据库表的尝试。

我是否必须首先显式运行 SELECT 语句并检查我要插入的值是否已经存在,或者我可以使用 PDO 异常处理它吗?

我现在正在做

    try{
        $stmt = $pdo->prepare("INSERT INTO table (column) VALUES (?) RETURNING id;");
        $stmt->execute( array('duplicate') );
    }
    catch( PDOException $e ){
        print $e;
    } 

这给了我

exception 'PDOException' with message 'SQLSTATE[23505]: Unique violation: 7 ERROR:  duplicate key value violates unique constraint "column"
DETAIL:  Key (column)=(duplicate) already exists.'

我认为如果能够在错误发生时发现它会更清晰,而不是首先检查该值是否已经存在(这首先会破坏具有 UNIQUE 约束的好处) .

最后,我想向用户显示一条用户友好的错误消息,例如“用户名已存在”

我想一个 hackish 方法是检查异常详细信息并根据它生成我的友好错误消息,但我可以相信这些详细信息(如 SQLSTATE[23505] 或代码 = 7)将来不会改变?

我能否构建一个更好的 SQL 语句,在重复约束失败时返回有用的信息(以及在成功时返回 id,就像现在一样)?

编辑

创建存储过程可能是一种解决方案:

CREATE OR REPLACE FUNCTION my_insert(a_value text)
RETURNS text AS $$
DECLARE
 retval text;
BEGIN
    INSERT INTO table (column) VALUES (a_value) RETURNING id INTO retval;
    RETURN retval;

    EXCEPTION
        WHEN unique_violation THEN
            retval = 'duplicate';
            RETURN retval;
END;
$$ LANGUAGE plpgsql;

,然后检查返回值是 'duplicate' 还是一个 id。

虽然它不能让我利用 PHP 异常来确定出了什么问题并生成友好的错误消息,但它确实消除了对单独的 SELECT 语句的需要。仍然对这个解决方案不完全满意,所以如果你知道更优雅的东西......

最佳答案

SQLSTATE代码在 SQL 标准中定义并且不太可能更改。他们自己可能并不总是提供足够的信息(因此有“详细信息”部分),但可以认为是可靠的。

关于php - 使用 PHP PDO 处理失败的 UNIQUE 约束?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35556110/

相关文章:

php - 如何在 laravel 5 中创建一个唯一的随机字符串

postgresql - Postgres 中的 Go 和 IN 子句

sql - PostgreSQL 索引性能问题

php - MySQL 查询有效,但 PHP 返回异常 : errorinfo:null

php - PHP DOM 有两个 HTML 问题:1.) DOMDocument::createEntityReference $name 值和 2.) 如何向一个元素添加多个 CSS 类?

php - 组合与继承依赖注入(inject)

php - session 变量可以被愚弄(登录)?

postgresql - Glassfish 4 和 Postgres ConnectionPool 上的 JSF 2.2 + EJB 3 + JPA

php - "Warning: PDO::prepare() expects parameter 2 to be array, string given"- 当仅指定一个参数时

php - 如何从 MYSQL 数据库中的最后 10 条记录中获取最小的 ID?