Very Fast PHP-MySQL interaction - php

i'm lookin for a way to make some kind of function into php and mysql who give me as a result the id of a record in a simple table.
I got a id -> value table where the id is an autoincrement field.
The natural way or the simple way i know is:
$myId = Check('Cheese');
function Check($value) {
$sql = "SELECT id FROM table WHERE value = '$value'");
$res = mysql_query($sql);
if ($res)
return mysql_result($res,0);
// If the record doesn't exist then continue to insert the record
$sql = "INSERT INTO table (value) values ('$value')";
$res = mysql_query($sql);
return mysql_insert_id();
}
Ok, I think this is the classic way .. but i think there must be a MySQL command or something who make things simpler.
I know there is a INSERT IGNORE but is there a way to make the select only if not exist and return the ID?
I want to do something like:
Select id from table
where value = 'dummy'
if not exist then
Insert into table (value) values ('dummy')
So i'll get the ID in one step and the MySQL will solve the problem and the code will be more efficient or quick ..
(imagine i got make this 10000 times)

use INSERT ... ON DUPLICATE KEY UPDATE
function Check($value) {
$sql = "INSERT INTO table (value) values ('$value') ON DUPLICATE KEY UPDATE value='$value'";
$res = mysql_query($sql);
return mysql_insert_id();
}
requires mysql 5.1.12 or later

You probably want WHERE NOT EXISTS. Take a look at the following sample to get an idea:
INSERT INTO table (value) SELECT id WHERE NOT EXISTS (SELECT * FROM table WHERE value='thing to check') LIMIT 1

If you are assuming that there is a high likelihood that most of Check() calls will eventually result in INSERTs, then you can do INSERT IGNORE and use mysql_affected_rows to check if there was an insert. If there was not an insert, then you can run a SELECT id FROM and use mysql_insert_id(). However, if it is more likely that the row exists, then you are better off running a SELECT statement first.
http://php.net/manual/en/function.mysql-affected-rows.php
If saving resources is your main goal that is. You are probably going to have to run both queries, even if they are combined into one statement.

Related

Mysql/PHP UPDATE the table + INSERT INTO an other table

Can I copy something to an other table and also update this in the same table?
Like:
INSERT INTO 'table_new' (name) values ("thomas")
At the same time:
UPDATE 'table_old' set ChangesWereMadeAt = (the date, where the changes were made)
Can I put something in other table, while it stays also in the old table and just updates one column ?
I work with PHP/MySql
use LAST_INSERT_ID();
INSERT INTO 'table_new' (name) values ("thomas");
$last_id_inserted = LAST_INSERT_ID();
UPDATE 'table_old' SET blah='$blah' WHERE id='$last_id_inserted';
Begin by inserting your new line into your table.
Then delete the line from the first table.
And finally copy the line you inserted with this:
INSERT INTO first_table
SELECT *
FROM dues
WHERE id = 5;
Like: INSERT INTO 'table_new' (name) values ("thomas")
At the same time:
UPDATE 'table_old' set ChangesWereMadeAt = (the date, where the
changes were made)
Based on this, I'd say the solution would be to make two requests.
This means... Can I put something in an other table while it stays also in the old table and just updates one column ?
But based on this, I could give a sort of solution.
$reqSelect= 'select * from YourTable
where [insert the condition that would make you select only the data you want to copy]';
$data = mysqli_query($connection, $reqSelect);
$reqInsert='insert into YourDestinationTable(row1, row2, etc)
values('.$data[row1].', '.$data[row2].', '.$data[etc]);
mysqli_query($connection, $reqInsert);
$reqUpdate='update YourTable where [conditions here]
set TheRowYouWantToModify = '.data[TheDataYouWantInYourRow];
mysqli_query($connection, $reqUpdate);
This sounds like it would be easier to solved my a MySql trigger. There is a basic example here: Creating Triggers to add the data into Audit Table

php num_rows not working

I have a simple function below to check if the user is already registered on my site. If they are then it doesn't add them and if they aren't it adds them. However In my database for some weird reason a certain user is getting added multiple times with the exact same id. Is there something wrong with mysqli_num_rows?
$check = mysqli_query($con, "SELECT id FROM users WHERE id='$id'");
$row_cnt = mysqli_num_rows($check);
if ($row_cnt == 0) {
$query = "INSERT INTO users (id,username) VALUES ('$id','$username')";
mysqli_query($con, $query);
} else { // If Returned user . update the user record
$query = "UPDATE users SET username='$username' where id='$id'";
mysqli_query($con, $query);
}
A few things here.
First of all, num_rows() notoriously doesn't always return the right value. If you want to know how many rows match some criterion, use this query then read the rowcount in the one-row resultset.
SELECT COUNT(*) AS rowcount FROM users WHERE id='$id'
Second, it looks like you're trying to do a conditional insert / update operation. In this case you will be best off using Use the INSERT ... ON DUPLICATE KEY UPDATE mySQL command. This gets around the race condition that is in the code in your question.
You want a query something like this:
INSERT INTO users (id,username) VALUES ('$id','$username')
ON DUPLICATE KEY UPDATE username='$username';
http://dev.mysql.com/doc/refman/5.6/en/insert-on-duplicate.html
This will either add the row you want or change the username in the existing row, all at once. If some other user tries to do the same thing at the same time, this will do it safely.

Check with sql if two tables are unique PHP

How can I check in MYSQL PHP if two columns are unique then not insert again, else if just one column is unique then insert, is that even possible to do in php?
EDIT:
Lets say I have a table like this,
userId | codeId
And I I send a query like this,
$query = $pdo->prepare('insert into table (userId, codeId) values (?,?)');
So now I want to check if userId and codeId are added already once do not insert again, and if just one is added, then do insert the entire query,
I hope its more understanding.
Set up a unique key for those columns, then the mysql query will FAIL when you try to insert.
Use REPLACE INTO instead of INSERT INTO ... ?
Do something like the code below (where TEXT_ID and TEXT_CATEGORY, are keys of table):
INSERT INTO
table_texts
SET
text_id = 174,
text_category = "pam_texto"
ON DUPLICATE KEY UPDATE
text_id = 174,
text_category = "pam_texto";
The above code tries to insert, but if the keys are duplicated performs an update on the line.

Database normalization and lazy development

I believe the question have emerged as my irritation of doing twice as much work as I could imagine is necessary.
I accept the idea that I could be lacking experience with both MySQL and PHP to think of a simpler solution.
My issue is that I have several tables (and I'd might be adding more) and of these is a parent table, only containing two fields - an id (int) and a name identifying it.
At this moment, I have seven tables with at least 15 fields in each one. Every table has a field, containing the id which I can link to the parent table.
All of these data isn't required to be filled - you will just have to create that one entry in the parent table. For the other tables, I have separate forms.
Now, these forms are made for updating the data in the fields, which means I have to pull out the data from the table if any data is available.
What I would like to do is when I receive the data from my form, I could just use an UPDATE query in my model. But if the table I want to update doesn't have an entry for that specific id, I need to do an insert.
So, my current pseudo code is like this:
$sql = "SELECT id FROM table_x WHERE parent_id = ".$parent_id;
$res = $mysql_query($sql);
if( mysql_num_rows($res) == 1 )
{
$sql = "UPDATE table_x SET ... WHERE parent_id = ".$parent_id;
}
else
{
$sql = "INSERT INTO table_x VALUES ( ... )";
}
mysql_query($sql);
I have two do this for every table I have - can I do something different or smarter or is this just the way it has to be done? Cause this seems very inefficient to me.
Use
INSERT ... ON DUPLICATE KEY UPDATE Syntax
It will insert if record not found,
otherwise, it will update existing record,
and you can skip the check before insert - details
This assuming relation for each 7 table to the parent table is 1:1
Or use REPLACE instead of INSERT - it's an insert, but will do an DELETE and then INSERT when a unique key (such as the primary key) is violated.
in mysql you can do this:
INSERT INTO table
(
col1,
col2
) VALUES(
'val1',
'val2'
) ON DUPLICATE KEY UPDATE table SET
col2 = 'val2'
take a look at the documentation for more information
mysql_query("UPDATE table table_x ..... WHERE parent_id=".$parent_id);
if (mysql_affected_rows()==0) {
mysql_query("INSERT INTO .....");
}

MySQL - ignore insert error: duplicate entry

I am working in PHP.
Please what's the proper way of inserting new records into the DB, which has unique field.
I am inserting lot of records in a batch and I just want the new ones to be inserted and I don't want any error for the duplicate entry.
Is there only way to first make a SELECT and to see if the entry is already there before the INSERT - and to INSERT only when SELECT returns no records? I hope not.
I would like to somehow tell MySQL to ignore these inserts without any error.
Thank you
You can use INSERT... IGNORE syntax if you want to take no action when there's a duplicate record.
You can use REPLACE INTO syntax if you want to overwrite an old record with a new one with the same key.
Or, you can use INSERT... ON DUPLICATE KEY UPDATE syntax if you want to perform an update to the record instead when you encounter a duplicate.
Edit: Thought I'd add some examples.
Examples
Say you have a table named tbl with two columns, id and value. There is one entry, id=1 and value=1. If you run the following statements:
REPLACE INTO tbl VALUES(1,50);
You still have one record, with id=1 value=50. Note that the whole record was DELETED first however, and then re-inserted. Then:
INSERT IGNORE INTO tbl VALUES (1,10);
The operation executes successfully, but nothing is inserted. You still have id=1 and value=50. Finally:
INSERT INTO tbl VALUES (1,200) ON DUPLICATE KEY UPDATE value=200;
You now have a single record with id=1 and value=200.
You can make sure that you do not insert duplicate information by using the EXISTS condition.
For example, if you had a table named clients with a primary key of client_id, you could use the following statement:
INSERT INTO clients
(client_id, client_name, client_type)
SELECT supplier_id, supplier_name, 'advertising'
FROM suppliers
WHERE not exists (select * from clients
where clients.client_id = suppliers.supplier_id);
This statement inserts multiple records with a subselect.
If you wanted to insert a single record, you could use the following statement:
INSERT INTO clients
(client_id, client_name, client_type)
SELECT 10345, 'IBM', 'advertising'
FROM dual
WHERE not exists (select * from clients
where clients.client_id = 10345);
The use of the dual table allows you to enter your values in a select statement, even though the values are not currently stored in a table.
from http://www.techonthenet.com/sql/insert.php
You can use triggers.
Also check this introduction guide to triggers.
Try creating a duplicate table, preferably a temporary table, without the unique constraint and do your bulk load into that table. Then select only the unique (DISTINCT) items from the temporary table and insert into the target table.
$duplicate_query=mysql_query("SELECT * FROM student") or die(mysql_error());
$duplicate=mysql_num_rows($duplicate_query);
if($duplicate==0)
{
while($value=mysql_fetch_array($duplicate_query)
{
if(($value['name']==$name)&& ($value['email']==$email)&& ($value['mobile']==$mobile)&& ($value['resume']==$resume))
{
echo $query="INSERT INTO student(name,email,mobile,resume)VALUES('$name','$email','$mobile','$resume')";
$res=mysql_query($query);
if($query)
{
echo "Success";
}
else
{
echo "Error";
}
else
{
echo "Duplicate Entry";
}
}
}
}
else
{
echo "Records Already Exixts";
}

Categories