Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I check a unique constraint with php?

Tags:

database

php

Maybe this question has already been asked, but I don't really know how to search for it:

I have the postgres-table "customers", and each customer has it's own unique name. In order to achieve this, I added an unique-constraint to this column.

I access the table with php.

When the user now tries to create a new customer, with a name that has already been taken, the database says "Integrity Constraint Violation", and php throws an error.

What I want to do is to show an error in the html-input-field: "Customer-Name already taken" when this happens.

My question is how I should do this.

Should I catch the PDO-Exception, check if the error-Code is "UNIQUE VIOLATION", and than display a message according to the Exception-Message, or should I check for duplicate names with an additional statement before I even try to insert a new row?

What is better practice? Making a further sql-statement, or catching and analyzing error-codes.

EDIT: I'm using transactions, and I'm catching any exception in order to rollback. The question is, if I should filter out Unique-violations so they don't lead to a rollback.

EDIT2: If I'm using the exception-method, I would have to analyse the exception-message in order to ensure that the unique-constraint really belongs to the "name"-column.

This is everything I get from the exception:

["23505",7,"FEHLER: doppelter Schlüsselwert verletzt Unique-Constraint <customers_name_unique>\nDETAIL: Schlüssel <(name)=(test)> existiert bereits."]

The only way to get information about the column is to check if "customers_name_unique" exists (it's the name of the unique-constraint).

But as you can also see, the message is in german, so the output depends on the system / might be able to change.

like image 665
maja Avatar asked Jul 16 '13 12:07

maja


3 Answers

You should catch the PDO exception.

It quicker to let the database fail, than to look up and see if the record already exists.

This also makes the application "less aware" of the business logic in the database. When you tell the database about the unique index that's really a business logic, and since the database is handling that particular logic it's better to skip the same check in the other layers (the application).

Also when the database layer is handling the exception you avoid race conditions. If your application is checking for consistency then you may risk that another user adds the same record after the first application has checked that it's available.

like image 139
Sven Tore Avatar answered Oct 22 '22 18:10

Sven Tore


The question doesn't really belong here but I'll answer you.

Exceptions are situations when something exceptional happens. It means that you shouldn't use them to handle situation that may happen oftenly. If you do it then it's like GOTO code. The better solution is to check previosly if there is any duplicate row. However, the solution with exceptions is easier so you need to decide if you want something to work or if you want to have something that works written as it should be.

like image 39
Robert Avatar answered Oct 22 '22 18:10

Robert


I would catch the exception, because (thanks to concurrency) that can happen anyway, even if you check with an extra query beforehand.

like image 30
Thilo Avatar answered Oct 22 '22 18:10

Thilo