Can I put a SELECT query into the IF statement in MySQL? - php

Well, I am getting some values from the main table say MTB and summarising it in some another table say STB using this script. There is no Unique or Primary key so I can't use ON DUPLICATE KEY situation here.
What I want to do is if the node name) fetched from the MTB Already exists in the STB Then I just want to update it and if the node name from MTB does not exist in the STB then I want to insert the data into the table.
I tried using the If case by first selecting the row in the STB using the nodename fetched from the MTB that if the nodename from the MTB is present in STB (i.e Select query IS NOT NULL) then We Update it else We insert it.
However, this fails to work. Kindly suggest that what I have done wrong.
IF (SELECT * FROM `NodesInfo` WHERE `Nodename` = '".$row2['nodeName']."') IS NOT NULL
THEN
UPDATE `NodesInfo` SET `Time Stamp`= '".$row2['timeStamp']."',`Status`= '$status' WHERE `Nodename` = '".$row2['nodeName']."'
ELSE
INSERT INTO `NodesInfo`(`Nodename`, `Category`, `Time Stamp`, `Type`, `Status`) VALUES ('".$row2['nodeName']."','NodeMCUMQTTData','".$row2['timeStamp']."','$type','$status')
END IF

Just look at the following code, it works.
For MYSQL :
$qry = mysqli_query(<set your db connection variable>, "SELECT * FROM `NodesInfo` WHERE nodeName` = '".$row2['nodeName']."' ");
$res = mysqli_num_rows($qry);
if($res > 0)
{
$update_qry = mysqli_query(<set your db connection variable>, "UPDATE `NodesInfo` SET `Time Stamp`= '".$row2['timeStamp']."',`Status`= '$status' WHERE nodeName` = '".$row2['nodeName']."'");
}
else
{
$insert_qry = mysqli_query(<set your db connection variable>, "INSERT INTO `NodesInfo`(`Nodename`, `Category`, `Time Stamp`, `Type`, `Status`) VALUES ('".$row2['nodeName']."','NodeMCUMQTTData','".$row2['timeStamp']."','$type','$status')");
}

IF exists(SELECT * FROM `NodesInfo` WHERE nodeName` = '".$row2['nodeName']."')
THEN
UPDATE `NodesInfo` SET `Time Stamp`= '".$row2['timeStamp']."',`Status`= '$status' WHERE nodeName` = '".$row2['nodeName']."'
ELSE
INSERT INTO `NodesInfo`(`Nodename`, `Category`, `Time Stamp`, `Type`, `Status`) VALUES ('".$row2['nodeName']."','NodeMCUMQTTData','".$row2['timeStamp']."','$type','$status')
END IF

It seems you want to update nodeName if it already exits otherwise inserts a new entry.
To achieve this, you can make your nodeName field unique.
ALTER TABLE `NodesInfo` ADD UNIQUE INDEX `idx_nodeName` (`nodeName`);
Now you can try ON DUPLICATE KEY UPDATE
INSERT INTO `NodesInfo`(`Nodename`, `Category`, `Time Stamp`, `Type`, `Status`) VALUES ('".$row2['nodeName']."',
'NodeMCUMQTTData',
'".$row2['timeStamp']."',
'$type','$status'
)
ON DUPLICATE KEY UPDATE
`Time Stamp`= '".$row2['timeStamp']."',
`Status`= '$status';

Related

ON Duplicate Key update doesn't work

I have used the following code to Insert/update MySQL table but its not doing anything when duplicate record exists I used ON Duplicate Key update. the code works great to insert but i want to update if description is differ from the source so i added this ON DUPLICATE KEY UPDATE PURCHASE_DESCRIPTION = VALUES ('$pdesc')" but it not inserting also not updating
mysqli_query($con,
"INSERT INTO table_name
(STOCK_NO, PURCHASE_DESCRIPTION, SALES_DESCRIPTION, itemId, itype, ITEM_DESCRIPTION, uOfM, uConvFact, poUOfM, lead, suplId, suplProdCode, minLvl, maxLvl, ordLvl, ordQty, unitWgt, sales, bomRev, makebuy) VALUES
('{$itemid}', '{$pdesc}', '{$sdesc}', '{$itemId}', '{$itype}', '{$itemdsc}', '{$uOfM}', '{$uConvFact}', '{$poUOfM}', '{$lead}', '{$supplId}', '{$suplProdCode}', '{$minLvl}', '{$maxLvl}', '{$ordLvl}', '{$ordQty}', '{$unitWgt}', '{$sales}', '{$bomRev}', '{$makebuy}')
ON DUPLICATE KEY UPDATE PURCHASE_DESCRIPTION = VALUES ('$pdesc')"
);
//STOCK_NO is the primary Key
Your SQL is incorrect. Take a look:
mysqli_query($con,
"INSERT INTO table_name
(STOCK_NO, PURCHASE_DESCRIPTION, SALES_DESCRIPTION, itemId, itype, ITEM_DESCRIPTION, uOfM, uConvFact, poUOfM, lead, suplId, suplProdCode, minLvl, maxLvl, ordLvl, ordQty, unitWgt, sales, bomRev, makebuy) VALUES
('{$itemid}', '{$pdesc}', '{$sdesc}', '{$itemId}', '{$itype}', '{$itemdsc}', '{$uOfM}', '{$uConvFact}', '{$poUOfM}', '{$lead}', '{$supplId}', '{$suplProdCode}', '{$minLvl}', '{$maxLvl}', '{$ordLvl}', '{$ordQty}', '{$unitWgt}', '{$sales}', '{$bomRev}', '{$makebuy}')
ON DUPLICATE KEY
-- HERE --
UPDATE PURCHASE_DESCRIPTION = '{$pdesc}'
");
Another option is UPDATE PURCHASE_DESCRIPTION = VALUES(PURCHASE_DESCRIPTION)
You can read more here: http://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html

PHP Assosiative array Insert into if data doesnt exist in table

I have an assosiative array in PHP which is inserting data into a table
foreach($array as $key => $value){
$query = "INSERT INTO live_list (file_id, date) SELECT ('$key', '$value') FROM dual WHERE NOT EXISTS (SELECT * FROM live_list WHERE file_id = '$key')";
mysqli_query($link, $query) or die('Query failed: ' . mysqli_error($link));
}
However as I have moved from an indexed array to an assosiative array, I can't figure out how to insert this data ONLY if the data in my array does not exist in my table.
Query failed: Operand should contain 1 column(s)
Now I am recieving this error
Any help will be great!
Why the use of a sub-query?
Assuming file_id is a unique field (i.e. no duplicates in the whole table), make it a unique index on the table if it isn't already:
ALTER TABLE live_list
ADD UNIQUE (file_id)
and change your query to
INSERT INTO live_list (file_id, date)
VALUES ('$key', '$value')
ON DUPLICATE KEY UPDATE date = date;
This means that it will simple "update" the value of date to what it already is if it encounters a duplicate key.
Although you should look to bind your parameters to protect against sql injection.
You could do this:
INSERT INTO live_list (file_id, date)
SELECT '$key', '$value'
FROM dual
WHERE NOT EXISTS (SELECT * FROM live_list WHERE file_id = '$key')
DUAL is a dummy table. The logic is that if the sub query does not exist, the dummy table returns one row with the desiered input.

Populating multiple tables when creating new primary record

I have been working on my first webapp and I hit a bit of a wall. I have a table in my db set up as follows:
student_id(student_id, first_name, last_name, bdate, etc...)
I also have several tables for classes set up similarly to this
class_table(id, student_id, quiz_1, quiz_2, etc....)
student_id is how I would like to track everything, from my understanding, this would be a primary key that would become a foreign key on the class tables.
What I would like to do is create an entry for the student on each class table when the php script I am writing creates a new student. This is what my query looks like:
$query = "INSERT INTO student_id(0, '$first_name', '$last_name'.... etc);".
"INSERT INTO class_table(0, LAST_INSERT_ID(), '$quiz_1', $quiz_2'...etc)";
Is this the right way to do this? I keep getting an error from my mysqli_query... so I am guessing this is where the problem is. How would I achieve this?
mysqli_query() (and mysql_query()) will only execute a single query. You would need to perform two calls to mysqli_query() or use mysqli_multi_query(), which will execute multiple queries in one call.
You're missing the VALUES clause:
$query = "INSERT INTO student_id VALUES (0, '$first_name', '$last_name'.... etc);".
"INSERT INTO class_table VALUES (0, LAST_INSERT_ID(), '$quiz_1', '$quiz_2'...etc)";
and you will need to use the mysqli_multi_query() function. See the example at http://www.php.net/manual/en/mysqli.multi-query.php#106126:
if ($mysqli->multi_query($query)) {
$i = 0;
do {
$i++;
} while ($mysqli->next_result());
}
if ($mysqli->errno) {
echo "Batch execution prematurely ended on statement $i.\n";
var_dump($statements[$i], $mysqli->error);
}
You could also create a stored procedure, and call it with all the needed parameters:
CALL insert_student('$first_name', '$last_name', '$quiz_1', $quiz_2', ... etc);
Here's an example:
CREATE PROCEDURE add_student(
IN v_first_name VARCHAR(50),
IN v_last_name VARCHAR(50),
IN v_quiz_1 VARCHAR(255),
IN v_quiz_2 VARCHAR(255)
)
DETERMINISTIC
MODIFIES SQL DATA
proc: BEGIN
START TRANSACTION;
INSERT INTO student_id VALUES (0, v_first_name, v_last_name);
IF ROW_COUNT() <= 0 THEN
ROLLBACK;
SELECT 0 AS result;
LEAVE proc;
END IF;
INSERT INTO class_table VALUES (0, LAST_INSERT_ID(), v_quiz_1, v_quiz_2);
COMMIT;
SELECT 1 AS result;
END;

How to get the id of the duplicated entry?

$query = "INSERT IGNORE INTO `user` (`name`, `email`) VALUES ( '".$name."', '".$email."')";
$res = mysql_query($query) or die("Query failed ".mysql_error() );
$last id = mysql_insert_id();
mysql_insert_id() return 0 if there is a duplicated entry.
Is there a way to get the ID of the duplicated entry ? or do I have to do 2 query ( SELECT + INSERT ) ?
There is no way with an INSERT to get the ID of the existing (duplicate) entry.
Still, you should not do a SELECT + INSERT because you would need to lock the table for concurrency (to ensure that nothing has changed between SELECT and INSERT).
In this case, if the insert fails, and you want to update the existing record instead, use INSERT ... ON DUPLICATE KEY UPDATE.
If you just want to fail, but have the existing ID, then fail, and do a SELECT to get the existing entry.

MySQL: Insert if this ip dont have any records

I use:
INSERT INTO `rating` (`name`, `user`, `rating`, `section`, `ip`)
VALUES ('$name', '{$_SESSION['user']}', '$rate', '$section',
'{$_SERVER['REMOTE_ADDR']}');";
I would like to add an if condition in the IF statement so that.
IF SELECT ip from rating
where ip={$_SERVER['REMOTE_ADDR']} AND section=$section AND name=$name
then update ELSE INSERT new row
is it doable or I better code it in php ?
thank you very much
P.s: I know how to do it with php, I want to learn it with MySQL.
Also i require that all 3 name,section,ip matchs not only ip
Assuming you have a unique constraint (UNIQUE index or PRIMARY KEY) on ip, section and name, you can use this syntax:
INSERT INTO `rating` (`name`, `user`, `rating`, `section`, `ip`)
VALUES ('$name', '{$_SESSION['user']}', '$rate', '$section', '{$_SERVER['REMOTE_ADDR']}')
ON DUPLICATE KEY UPDATE user = VALUES(user), rating = VALUES(rating);
To expand on Eric's excellent answer.
To add a unique constraint on each of the columns ip, name, section run the following code on the database
ALTER TABLE `test`.`rating`
ADD UNIQUE INDEX `name`(`name`),
ADD UNIQUE INDEX `section`(`section`),
ADD UNIQUE INDEX `ip`(`ip`);
To run a unique constraint on the combination of columns ip+name+section do:
ALTER TABLE `test`.`rating`
ADD UNIQUE INDEX `name_section_ip`(`name`, `section`, `ip`);
The last thing is probably what you want.
One last thing
I'm not 100% sure, but this usage of {$_SERVER['REMOTE_ADDR']} in the query does not look SQL-injection safe.
Consider changing it into:
$remote_adr = mysql_real_escape_string($_SERVER['REMOTE_ADDR']);
$session = mysql_real_escape_string($_SESSION['user']);
$query = "INSERT INTO `rating` (`name`, `user`, `rating`, `section`, `ip`)
VALUES ('$name', '$session', '$rate', '$section','$remote_adr')";
Finally putting a ";" in a mysql_query() like so mysql_query("select * from x;"); does not work mysql_query() will only ever execute one query and will reject your ;.

Categories