Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

check for duplicate entry vs use PDO errorInfo result

Tags:

php

mysql

pdo

I have a MySQL table which has a field for email addresses which is defined as unique. For this example, let's say that all my form does is allow a user to insert their email address into the table.

Since the email field is unique, the query should fail should they try to enter the same email twice. I'm curious about the trade-offs between between the two scenarios:

1) Run a quick SELECT statement before performing the insert. If the select returns results, inform the user, and do not run the INSERT statement.

2) Run the INSERT statement, and check for a duplicate entry error

// snippet uses PDO if (!$prep->execute($values)) {     $err = $prep->errorInfo();     if (isset($err[1]))     {         // 1062 - Duplicate entry         if ($err[1] == 1062)             echo 'This email already exists.';     } } 

Also, please assume normal use, meaning that duplicate entries should be minimal. Therefore, in the first scenario you obviously have the overhead of running an additional query for every insert, whereas in the second you're relying on error handling.

Also, I'm curious to hear thoughts on coding style. My heart says 'Be a defensive programmer! Check the data before you insert!' while my brain says 'Hmmm, maybe it's better to let MySQL take care of checking the data for you'.

EDIT - Please note this isn't a "How do I do this" question, but rather a "Why should I do this a particular way" question. The little code snippet I included works, but what I'm curious about is the best way to solve the problem.

like image 933
JoshBramlett Avatar asked May 27 '12 15:05

JoshBramlett


People also ask

How can I check my PDO?

Generally you can just do phpinfo(); to find out what modules are installed. Additionally you could use: class_exists('PDO') to find out whether the PDO class indeed is accessible. php -m does not show PDO, pdo_mysql, or pdo_sqlite, all of which are present in my dev box.

What is the purpose of PDO :: errorInfo () data?

PDO::errorInfo only retrieves error information for operations performed directly on the database. Use PDOStatement::errorInfo when a PDOStatement instance is created using PDO::prepare or PDO::query. Support for PDO was added in version 2.0 of the Microsoft Drivers for PHP for SQL Server.


2 Answers

You could be executing this with a try catch block:

try {    $prep->execute($values);    // do other things if successfully inserted } catch (PDOException $e) {    if ($e->errorInfo[1] == 1062) {       // duplicate entry, do something else    } else {       // an error other than duplicate entry occurred    } } 

You could also look into alternatives such as "INSERT IGNORE", and "INSERT... ON DUPLICATE KEY UPDATE" - though I think those are MySQL specific and would go against the portability of using PDO, if that's something you're concerned about.

Edit: To more formally answer your question, to me, solution #1 (the defensive programmer) in full usage effectively eliminates the point of the unique constraint in the first place. So I would agree with your thought of letting MySQL take care of data checking.

like image 198
Dan LaManna Avatar answered Sep 21 '22 00:09

Dan LaManna


INSERT + check status should be a better approach. With SELECT + INSERT you can have another thread insert the same value between the SELECT and the INSERT, which means you would need to also wrap those two statements in a table lock.

It is easy to err on the side of too much defense in your coding. Python has the saying that "it is easier to ask for forgiveness than to ask for permission", and this philosophy is not really Python-specific.

like image 42
lanzz Avatar answered Sep 17 '22 00:09

lanzz