MySQL行中的UNIQUE约束

时间:2014-03-22 14:47:32

标签: mysql sql duplicates

我正在我的数据库中执行INSERT查询:

$query = "INSERT IGNORE INTO user VALUES ('', 0, $safe_email, '$hashed_password')";

$result = $db->query($query);

db表中的第3行是email,我为其设置了一个唯一约束。

如果我尝试插入重复的电子邮件,请使用上面的查询通知我INSERT IGNORE如果它与数据库中已存在的那个重复,则不会插入该记录,但是不会给出错误或任何迹象表明正在尝试插入重复记录。

我想显示一条很好的错误消息,如果找到重复但是INSERT IGNORE我正在努力做到这一点,因为它不会显示错误,它会忽略查询。

所以我需要这样的东西:

IF (duplicate entry found in db){
echo "User already exists";
}
END IF

2 个答案:

答案 0 :(得分:0)

根据INSERT ... IGNORE上的文档:

  

如果使用IGNORE关键字,则忽略执行INSERT语句时发生的错误。例如,如果没有IGNORE,则复制表中现有UNIQUE索引或PRIMARY KEY值的行会导致重复键错误,并且语句将中止。使用IGNORE时,仍未插入行,但不会发生错误。忽略错误可能会生成警告,但重复键错误不会。

您可以从脚本语言或SQL界面发出show warnings;或任何兼容的类似语句。如果它返回一个或多个这样的警告,可能是其中一个可能出现此类插入问题。使用它们,您可以向最终用户显示正确的错误或安慰消息。


修改1

  

... but ... how do I throw my own error message instead of the default exception when using INSERT without the IGNORE

您可以定义BEFORE INSERT触发器以识别重复数据行,并在找到时抛出自定义错误消息。

示例

delimiter //

drop trigger if exists bi_table_trigger //

CREATE TRIGGER bi_table_trigger BEFORE INSERT ON table
FOR EACH ROW
BEGIN
  declare rowCount int default 0;
  declare error_message varchar(1024) default '';

  SELECT COUNT(1) into rowCount FROM table 
  WHERE email = NEW.email;

  IF ( rowCount > 0 ) THEN -- if( rowCount ) -- too works
    set error_message = 
        concat( error_message, 'User with email \'' );
    set error_message = 
        concat( error_message,  NEW.email, '\' ' );
    set error_message = 
        concat( error_message, 'already exists' );

    -- throw the error
    -- User with email '?' already exists  ( example )
    signal sqlstate 1062 set message_text = error_message;
  END IF;
END;//

delimiter ;

答案 1 :(得分:0)

使用普通插入查询并在try-catch语句中实现查询。 '插入'如果您尝试插入相同的电子邮件,查询将失败,因为它是唯一约束。所以你可以抓住例外,因为'插入'查询失败。

示例:

try { 
"your insert query";
} catch (Exception $e) { 
"your insert failure exception"
} 

注意:您可以捕获执行插入查询期间发生的所有异常,这将更有帮助