I want to edit a table from my database.That table have many data.
I will show sample.Do I need to write many mysql update statement?Have other method to write a only one statement? I am beginner for php? Thank all my friend.Sorry for my english.
mysql_query("UPDATE `mytablename` SET `mobiletitle` = '$mobiletitle1',
`mobilepublished` = '1',
`mobiletext` = '$mobilefulltext1',
WHERE `id` ='$id1';");
mysql_query("UPDATE `mytablename` SET `mobiletitle` = '$mobiletitle2',
`mobilepublished` = '1',
`mobiletext` = '$mobilefulltext2',
WHERE `id` ='$id2';");
mysql_query("UPDATE `mytablename` SET `mobiletitle` = '$mobiletitle3',
`mobilepublished` = '1',
`mobiletext` = '$mobilefulltext3',
WHERE `id` ='$id3';");
etc.............
mysql_query("UPDATE `mytablename` SET `mobiletitle` = '$mobiletitle30',
`mobilepublished` = '1',
`mobiletext` = '$mobilefulltext30',
WHERE `id` ='$id30';");
You want to update multiple rows from one table with specific data, so bad news you have to do it one by one.... but you can improve your code. If I where you I will create a function and I just call it, something like
function update_my_data($movilefilltex1,$id1){
mysql_query("UPDATE `mytablename` SET `mobiletitle` = '$mobiletitle1',
`mobilepublished` = '1',
`mobiletext` = '$mobilefulltext1',
WHERE `id` ='$id1';");
.......
}
So to make the multiple insert you can call update_my_data(value1,valu2) the times that you need. for example in a loop or just whenever you need it.
If there is a UNIQUE index on id (and there will be if it's your PRIMARY KEY), you could use INSERT ... ON DUPLICATE KEY UPDATE:
INSERT INTO mytablename (id, mobiletitle, mobilepublished, mobiletext) VALUES
('$id1', '$mobiletitle1', 1, '$mobilefulltext1'),
('$id2', '$mobiletitle2', 1, '$mobilefulltext2'),
-- etc.
ON DUPLICATE KEY UPDATE
mobiletitle = VALUES(mobiletitle),
mobilepublished = VALUES(mobilepublished)
mobiletext = VALUES(mobiletext);
Note that this will, of course, insert new records if they don't already exist; whereas your multiple-UPDATE command approach will not (it would raise an error instead).
In either case, you could build/execute the SQL dynamically from within a loop in PHP.
I would also caution that you would be well advised to consider passing your variables to MySQL as parameters to a prepared statement, especially if the content of those variables is outside of your control (as you might be vulnerable to SQL injection). If you don't know what I'm talking about, or how to fix it, read the story of Bobby Tables.
Putting it all together (using PDO instead of the deprecated MySQL extension that you were using):
for ($i = 1; $i <= 30; $i++) {
$sqls[] = '(?, ?, 1, ?)';
$arr[] = ${"id$i"};
$arr[] = ${"mobiletitle$i"};
$arr[] = ${"mobilefulltext$i"};
}
$sql = 'INSERT INTO mytablename (id, mobiletitle, mobilepublished, mobiletext)
VALUES
' . implode(',', $sqls)
. 'ON DUPLICATE KEY UPDATE
mobiletitle = VALUES(mobiletitle),
mobilepublished = VALUES(mobilepublished)
mobiletext = VALUES(mobiletext)';
$db = new PDO("mysql:dbname=$db", $user, $password);
$qry = $db->prepare($sql);
$qry->execute($arr);
Note that you might also consider storing your 1..30 variables in arrays.
update table1,table2 SET table1.column1 = 'valueX',table2.coulumn2 = 'valueX' where table1.column = table2.coulumn2 ;
Related
I have an array like:
$postdata[1] = 'This';
$postdata[2] = 'That';
$postdata[3] = 'The other';
And I want to loop through the array and update all of the rows where ID corresponds to the array key. Like:
foreach ($postdata as $key => $value) {
if ($key == 1) {
$update = $db->query("UPDATE site_email_templates SET Content='$postdata[1]' WHERE ID = 1");
} else if ($key == 2) {
$update = $db->query("UPDATE site_email_templates SET Content='$postdata[2]' WHERE ID = 2");
} else if ($key == 3) {
$update = $db->query("UPDATE site_email_templates SET Content='$postdata[3]' WHERE ID = 3");
}
}
What would be the simplest way to do this, not particularly knowing how many array keys there are, and keeping it all in one query?
You need to use prepared statements in order to avoid errors and vulnerabilities of all sorts and also to get some minor performance gain
$stmt = $db->prepare("UPDATE site_email_templates SET Content=? WHERE ID = ?");
$stmt->bind_param("ss", $content, $id);
foreach ($postdata as $id => $content)
{
$stmt->execute();
}
Reference: How can I prevent SQL injection in PHP?
Note: My answer is based on the PDO driver which in many aspects is better than mysqli. If you need mysqli solution please check the other answer provided by #Your Common Sense
The code below is tested on real environment and served with prepared statement preventing SQL-injection:
$sql = "UPDATE `site_email_templates` SET `Content` = (:content) WHERE `Id` = (:id)";
$stmt = $dbConn->prepare($sql);
foreach ($postdata as $id => $content)
{
$stmt->execute([':id' => $id, ':content' => $content]);
}
For more details about SQL injection you can read more:
https://www.owasp.org/index.php/SQL_Injection
For maximal speed, IODKU can do all the updates in a single statement. Caution: You should not use this for updating if you don't know that the ids exist.
INSERT INTO t
(id, -- A PRIMARY or UNIQUE key
col1, col2) -- column(s) to change
VALUES
(111, 22, 33),
(222, 33, 44),
...
ON DUPLICATE KEY UPDATE
col1 = VALUES(col1),
col2 = VALUES(col2);
You must provide some way to "bind" or "escape" the values to avoid sql-injection.
I have a query which I would like to INSERT some data into my table however, if there is already data inside of a particular field checkPoint, then run an UPDATE. After a lot of research on here, users have suggested using ON DUPLICATE KEY.
This query works however as apposed to updating an already existing row, it inserts a new one, with a new primary key, please can someone explain where I have gone wrong, or what I've missed out.
<?php
$idUsers = $_SESSION['id'];
$ModuleID = 5;
$checkPoint = 999;
$query= "INSERT INTO `userTakingModule` (`userTakingModuleID`, `idUsers`, `ModuleID`, `checkPoint`) VALUES (NULL, $idUsers, $ModuleID, $checkPoint) ON DUPLICATE KEY UPDATE `idUsers` = VALUES ($idUsers), `ModuleID` = VALUES ($ModuleID), `checkPoint` = VALUES ($checkPoint) ";
$result = $conn -> query($query);
?>
Screenshot of my database layout: the table called userTakingModule in the middle is where the query is applied to.
This is what is happening at the moment as I need to include the Primary Key of userTakingModuleID into the query somehow. (I almost need to say, look for where there is an already existing entry of the same idUser and ModuleID?)
The important part of using INSERT...ON DUPLICATE KEY UPDATE is telling MySQL what the key is, so it can look for duplicates. You said:
I almost need to say, look for where there is an already existing entry of the same idUser and ModuleID
And that's exactly right. You need to create a UNIQUE index on those two columns like so:
ALTER TABLE userTakingModule ADD UNIQUE INDEX(idUser, ModuleID);
Now, conflicts will trigger the update functionality. You should just remove the userTakingModuleID column from your query altogether, it will be given a value automatically as needed. You're also mis-using the VALUES function; you should pass it a column name, and it will resolve to the value that would have been inserted into that column without a conflict. So you can use either the VALUES function, or the variable itself.
And speaking of variables, I would be remiss if I didn't point out how insecure and dangerous it is to insert variables directly into queries. You should always use prepared statements. You don't provide enough code to know which database API you're using, but for PDO it would look like this:
$idUsers = $_SESSION['id'];
$ModuleID = 5;
$checkPoint = 999;
$query= "INSERT INTO userTakingModule (idUsers, ModuleID, checkPoint) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE idUsers = VALUES (idUsers), ModuleID = VALUES (ModuleID), checkPoint = VALUES (checkPoint)";
$stmt = $conn->prepare($query);
$stmt->execute([$idUsers, $ModuleID, $checkPoint]);
$data = $stmt->fetchAll(\PDO::FETCH_ASSOC);
And for mysqli something like this (though I'm not too familiar with it)
$idUsers = $_SESSION['id'];
$ModuleID = 5;
$checkPoint = 999;
$query= "INSERT INTO userTakingModule (idUsers, ModuleID, checkPoint) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE idUsers = VALUES (idUsers), ModuleID = VALUES (ModuleID), checkPoint = VALUES (checkPoint)";
$stmt = $conn->prepare($query);
$stmt->bind_param("iii", $idUsers, $ModuleID, $checkPoint);
$stmt->execute();
$result = $stmt->get_result();
what is the best way to write the query if row exist update else insert new record? I was trying the rubbish code as listed below:
<?php
for ($i = 0; $i < ($_POST['count']); $i++) {
$form_details_subquestion_id = $_POST['form_details_subquestion_id'][$i];
$form_details_section_id = $_POST['form_details_section_id'][$i];
$mark = $_POST['mark'][$i];
$remark = $_POST['remark'][$i];
$result = $db->query("
SELECT *
FROM audit_section_markrecord
WHERE
form_details_subquestion_id = $form_details_subquestion_id AND
audit_section_no = $audit_no
");
if ($result->num_rows == 1) {
$query2 = "
UPDATE audit_section_markrecord
SET
mark = '$mark',
dateofmodify = '$date'
WHERE
form_details_subquestion_id = '$form_details_subquestion_id' AND
audit_section_no = '$audit_no'
";
$result2 = $db->query($query2);
$query3 = "
INSERT INTO markrecord_update_details (
audit_section_no,
form_details_subquestion_id,
form_details_section_id,
mark,
userlog,
ipaddress
) VALUES (
'$audit_no',
'$form_details_subquestion_id',
'$form_details_section_id',
'$mark',
'$user_staff',
'$ip'
)
";
$result3 = $db->query($query3);
} else if ($result->num_rows == 0) {
$query4 = "
INSERT INTO audit_section_markrecord (
audit_section_no,
form_details_subquestion_id,
form_details_section_id,
mark
) VALUES (
'$audit_no',
'$form_details_subquestion_id',
'$form_details_section_id',
'$mark'
)
";
$result4 = $db->query($query4);
} else {
echo "<script>alert('Error. Please contact IT support.')</script>";
echo "<script language='javascript'>window.location.href='index.php'</script>";
}
}
The above code is writing inside for loop. I try to get if the form_details_subquestion_id AND audit_no is exist then update old records and insert to markrecord_update_details;else insert new records.
I don't know how to use the most easier to write the code. I just try to learn from this journey.
Best way is insert on duplicate key update.
Explanation for first query.
/* execute this directly in MySQL to add unique key constraint*/
ALTER TABLE audit_section_markrecord
ADD UNIQUE(form_details_subquestion_id, audit_section_no);
/* this query is for calling from php */
INSERT INTO audit_section_markrecord
SET
/* try to insert value */
mark = '$mark',
dateofmodify = '$date',
form_details_subquestion_id = '$form_details_subquestion_id',
audit_section_no = '$audit_no'
/* if constraint check fails, i.e. */
/* there is a row with this form_details_subquestion_id and audit_section_no */
/* then just update mark and dateofmodify */
ON DUPLICATE KEY UPDATE
mark = '$mark',
dateofmodify = '$date';
P.S. Escape you data to prevent sql-injection!
P.S2. To check it works, run 2 queries in MySQL:
INSERT INTO audit_section_markrecord
SET
mark = 'good',
dateofmodify = '2015-11-10',
form_details_subquestion_id = 10,
audit_section_no = 23;
INSERT INTO audit_section_markrecord
SET
mark = 'good',
dateofmodify = '2015-11-10',
form_details_subquestion_id = 10,
audit_section_no = 23
ON DUPLICATE KEY UPDATE
mark = 'excellent',
dateofmodify = '2015-11-26';
Row should have mark=excellent and dateofmodify=2015-11-26.
P.S3. If it's inserting duplicate rows, there was a problem with adding the unique key. Take a look at SHOW CREATE TABLE audit_section_markrecord. (Thanks Barmar).
#Andrew, seems I'v understood your needs.
You want to update markrecord_update_details only if audit_section_markrecord was updated (not inserted).
You check for update needed by combination of two columns: form_details_subquestion_id and audit_section_no.
Seems your code is working fine. Use it, don't complicate things.
I suggest you to postpone leaning "easier way" to do work. Add data escaping to prevent sql-injection and relax.
P.S. When you will be ready, google "mysql triggers on update", "unique key" and "on duplicate key update" (my prev example has some foundation for it).
Another way is to use a REPLACE statement. It works just like an INSERT statement, but when it tries to insert the record, if a record with the same keys exists then deletes the old record and inserts the new one. Since you are not updating based on previous values, this might be easier to work.
The user will need DELETE rights so this works.
Example:
$query4 = "REPLACE INTO `audit_section_markrecord` (audit_section_no,form_details_subquestion_id, form_details_section_id, mark) VALUES
('$audit_no', '$form_details_subquestion_id', '$form_details_section_id', '$mark') ";
So, I've got a few txt files, each container around 400,000 lines.
Each line is a word, I need to add to my database, if it isn't in there already.
Currently my code for checking/adding every word is
$sql = mysql_sql("SELECT `id` FROM `word_list` WHERE `word`='{$word}' LIMIT 1");
$num = mysql_num($sql);
if($num == '0'){
$length = strlen($word);
$timestamp = time();
#mysql_sql("INSERT INTO `word_list` (`word`, `length`, `timestamp`) VALUES ('{$word}', '{$length}', '{$timestamp}')");
}
and the functions being called are:
function mysql_sql($sql){
global $db;
$result = $db->query($sql);
return $result;
}
function mysql_num($result){
return $result->num_rows;
}
I'm looking for a better way to insert each word into the database.
Any ideas would be greatly appreciated.
I can think of some ways to do this.
First, if you have access to the MySQL server's file system you can use LOAD DATA INFILE to create a new table, then do an insert from that new table into your word_list table. This will most likely be your fastest option.
Second (if you don't have access to the MySQL server's file system), put a primary key or unique index on word_list.word. Then get rid of your SELECT query and use INSERT IGNORE INTO word_list .... That will allow MySQL automatically to skip the duplicate items without any need for you to do it with a query/insert operation.
Third, if your table uses an access method that handles transactions (InnoDB, not MyISAM), issue a BEGIN; statement before you start your insert loop. Then every couple of hundred rows issue COMMIT;BEGIN; . Then at the end issue COMMIT;. This will wrap your operations in multirow transactions so will speed things up a lot.
Try out this code. It will first create query with all your values and you will run query only ONCE ... Not again and again for ever row
$values = array();
$sql = mysql_sql("SELECT `id` FROM `word_list` WHERE `word`='{$word}' LIMIT 1");
$num = mysql_num($sql);
$insert_query = "INSERT INTO `word_list` (`word`, `length`, `timestamp`) VALUES ";
if ($num == '0') {
$length = strlen($word);
$timestamp = time();
$values[] = "('$word', '$length', '$timestamp')";
}
$insert_query .= implode(', ', $values);
#mysql_sql($insert_query);
Method for inserting data into two tables:
We do transfer the 2nd table in our Database.
I made a separate connection for two tables.
table name is transaction_held_record
The columns that I need to fill-in was:
transaction_desc
product_code
product_name
selling-price
Here's the sample code for the first table:
include("system/connxn.php");
if (!isset($_POST['eid'])) customError("Failed: Invalid access.", $log);
//Columns for first table.
$eid = $_POST['eid'];
$customer = $_POST['customer'];
$title = $_POST['title'];
$startTime = $_POST['startTime'];
$endTime = $_POST['endTime'];
$roomID = $_POST['roomID'];
$personnel = $_POST['personnel'];
$service = $_POST['service'];
$status = $_POST['status'];
$remarks = $_POST['remarks'];
$adjustment = $_POST['adjustment'];
$totalprice = $_POST['totalprice'];
$query_str = "UPDATE reservationlist SET `title` = '$title', `start` = '$startTime', `end` = '$endTime', `customer` = '$customer', `resource` = '$roomID', `personnel` = '$personnel', `services` = '$service', `status` = '$status', `remarks` = '$remarks', `totalprice` = '$totalprice', `modflag` = '$adjustment' WHERE id = $eid";
//echo $query_str;
mysql_query($query_str) or customError("Failed: (".mysql_errno().") ".mysql_error(), $log);
//echo mysql_insert_id();
$log->writelog("Update on table [reservationlist] record id: ".$eid);
echo "Saved";
Thank you guys!
You may create A PHP class with two(2) functions. One function that receives arguments(parameters) for the values to be updated by record id to the first table and another function for the other table. for example:
class dbUpdates
{
function updateReservations($eid, $val1, $val2, $val3, $val4, $val5) {
mysql_query("UPDATE reservationlist SET ... WHERE id = $eid");
//do handling or some additional codes here...
}
function insertTransaction($recid, $val1, $val2, $val3, $val4, $val5) {
mysql_query("INSERT INTO transaction_held_record (reffield, val1field, val2field, val3field, val4field, val5field) VALUES($recid, $val1, $val2, $val3, $val4, $val5)");
//do handling or some additional codes here...
}
}
Include the class file include("dbUpdates.php");
Instantiate the class by
$updateDB = new dbUpdates;
and you may call the functions $updateDB->updateReservations("your arguments here..."); and $updateDB->insertTransaction("your arguments here...");
hope this helps a bit...
Correct me if I'm wrong.You need to insert data into two different tables, in two different databases?
for this you need two connection and an script for each one. check if the first script has succeeded then run the second.
but if you could somehow access both tables with one connection, you could run both your scripts in one action!
UPDATE: I think you need to get the ID of the inserted row in first table and use that for second table, right?
do like this : How to get the ID of INSERTed row in mysql?
UPDATE: you can do multiple update, insert query you want done in a single action.like:
$query = "UPDATE `tbl_something` SET col1 = 'first' WHERE col1 LIKE '%something%';INSERT INTO tbl_another (col1 , col2 , col5) VALUES ('firstValue' , 'secondValue' , 'fifthValue');UPDATE ... ; ";
then run it with mysq_query($query);
if you want you can get the id of effected row in the query, like I mentioned earlier and use it in the next one.
hope this helped