问题:使用 PHP PDO 处理失败的 UNIQUE 约束?

我正在使用 PostgreSQL 和 PHP(使用 PDO)构建一个简单的 Web 应用程序。我在一列上有一个 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 ]或code u003d 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 标准中定义的,不太可能更改。他们自己可能并不总是提供足够的信息(因此是“详细信息”部分),但可以认为是可靠的。

Logo

PostgreSQL社区为您提供最前沿的新闻资讯和知识内容

更多推荐