我正在使用 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/