Kohana Model with unique key on two columns - php

I have a database with a table categories which has a unique key on item_id and user_id. When I'm adding new categories in my controller it using:
$category = new Model_Category();
$category->item_id = $item_id;
$category->user_id = $user_id;
$category->save();
Kohana 3.2 returns a "Duplicate entry '1-3' for key" error. Is it better practice to wrap it in a try/catch or would it be better to check whether the unique key already exists before trying to add it?

I would advice on a try catch, since it uses one less query to check for the duplicate key, however that might limit the amount of information you can display to the user since im not sure if the exception contains the actual column that violates the key, i think its just a generic error so if you want to actually check which of the two columns gives the error you might wanna use a query before that. Hope it helps. FYI i use try catch most of the time, its cleaner and easy to log errors.

Related

Error handling for SQL UNIQUE Constraint?

Can there be any proper error handling be implemented into a SQL UNIQUE Constraint? So far i'm obviously getting: Error: Duplicate entry 'test1' for key 'username'
But i'd like to have it display a custom comment if possible
You should check in your app code before inserting this
row that no other row exists with the same username.
Then if it exists, show the error you want to the user.
Parsing this unique constraint error
(after you get it) is not a good idea.
So do it before, not after.

Check duplicates SQL or php?

I have a field in my users database, a 6 digit number that is generated upon registration. I use mt_rand(100000, 999999) to generate the numbers.
Now to the question, to make sure no one gets the same number I need to either make the field UNIQUE (which i think seems the best) instead of some PHP code. Maybe theres some other way I don't know. The question is, whats the best way to do this?
You can do this way using PHP.
First give a unique constraint to the field.
if (mysqli_errno() == 2027)
mysqli_query("INSERT INTO ... {mt_rand()}");
So, once you insert a duplicate value, it gives out an error code 2027, saying duplicate. You can resubmit the query.
Why don't you
use a nested select to get the max(user_id), increase it and use that value for the new user?
create a table that holds just the current user-id and fetch, increase and use that value to create the new user?
use an AUTO_INCREMENT column?
Use an AUTO_INCREMENT column.
Performing a query to check if a generated number already exists is a bad solution and become worse with more and more users registered because more number are used, so you need to keep trace of all generated numbers to always generate a valid number.
With an AUTO_INCREMENT column, this occurs "automatically" .

duplicate data avoiding in codeigniter datamapper !? PHP

I am inserting the Food(table) keys/enteries into the DB and I get duplicate keys even though I am not suppose to based on the manual. I am really confused and stuck!?
Relationship is as follows: every user has a related to many different food types. Then whenever I read the user's $data['food'] agin...It creates a duplicate entry . Meaning that next time the user logs in instead of knowing that food exits. it increments the primary key and does not understand that the key exits contrary to what manual suggest that save is smart enough to know that...So my problem is I want to have only one copy of every entry but I end up with more entries. How Can I avoid having duplicate entries ?
for(i=0; sizof($data['food']);i++){
$f=new Food();
$f->food_id=$food['id'];
$f->name=$food[$j]['name'];
$f->user_id=$food_id;
$u=new User();
$u->where('user_id',$food)->get();
//save food and the relationship
$fm->save($f);
}
Why did you set your user_id to be the same as food_id?
The code you wrote to get the user details, doesn't seem to be doing anything too.

ORM (RedBean) and duplicate keys

I am currently using RedBean for ORM in my models.
I need to insert data into a MySQL table where one of the columns is set to unique.
Currently, data is inserted via a form like so:
//Create
$object = R::dispense('object');
//Need to check if supplied name is a duplicate
$object->name = $name
$object->description = $description
//Save
R::store($object)
Now the problem is that if $name was not duplicated in the database, everything goes well. If it is a duplicate, I can catch the exception and get the SQL error code: 23000
If I echo the exception, I get:
[23000] - SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'abc' for key 'name_UNIQUE'
Another problem is that if I have multiple fields which are set to UNIQUE, the exception will only tell me the first field that's duplicated. Therefore, in order to get the next field, I need to make sure the user corrects the first duplicate and run the query again.
This seems to be quite inefficient. I need to be able to check if the user has inserted duplicate data in multiple fields while not executing too many SQL statements.
What are some best practices for doing this? Also, what's the best practice when it comes to returning whether the action was a success, or if on failure, why and which fields back to the controller?
Thank you :)
You must first perform a "select" to check that the unique entries do not already exist, there is no other way... If you do not want to perform multiple requests from you code, you can implement a stored procedure.
It allows you to perform multiple requests within the same transaction, and that limits the network overhead.
It will also allow you to manage multiple kinds of error (through error codes AFAIR), which will give you a way to identify clearly the problematic field.
Check out this link
Hope that helps !

Check for Duplicates in a Database Before Entering Data

Before Entering data into a database, I just want to check that the database doesn't have the same username in the database already.
I have the username in SQL set as a key, so it can't be duplicated on that end, but I am looking at finding a more user-friendly error message then "KEY already exists".
Is there are simple way to check if the variable value already exists in a row?
Either preform a check before attempting the insert, or catch the exception and display it in a more clean and user-friendly way in your application.
Edit: Take a look at this tutorial on PHP exception handling. You probably want to wrap your query execution in a try-catch block, like so:
try
{
// do your query here (it's been forever since I've used PHP)
}
catch(Exception $e)
{
// display a clean error to the user
}
Except, instead of catching a general type Exception, you'll want to figure out what sort of exception you're actually getting (something like MySQLDuplicateKeyException, or whatever it may be - echo the exception you get when testing, and use that). This way, you won't display an error informing the user of an existing username, if in fact, there is another problem (like a DB connection error, for instance).
Good luck!
The technique to check whether data exists is to issue the query:
SELECT COUNT(*) FROM YourTable WHERE YourKeyCol = YourKeyValue
and then examine the first returned column of the only returned row in the dataset. If it contains 0, the data wasn't there, otherwise it was found.
But as others have pointed out, you can just go ahead and issue your INSERT. Examine the error code to determine whether it failed. This is more performant because, for those cases where the data is not already in the database, you will execute only one query instead of two.
There might be a special way to do this depending on what RDBMS you are using.
For example, using MySQL, you can say
INSERT INTO table (username,value) VALUES ('foo',123) ON DUPLICATE KEY UPDATE value = 123;
Since you've already set username to be a unique key, this will insert ('foo',123) into table only if foo is not already in the table. If it does exist, then the value is updated.
Or, you could use something like
INSERT IGNORE INTO table (username,value) VALUES ('foo',123)
which ignores the insert if foo is already in the table.
I can think of two ways to do this.
The first is simply to do a select statement beforehand on that username to detect any duplicates. If a row is returned then you know that that username already exists.
The other is that you can get mysql to return the error number using mysql_errno, you can then simply have an if statement that checks for a specific error number. The only problem with this that it may not indicate which field is a duplicate of the key.
I have used a pre select statement in my scripts.

Categories