I currently have the following update statement but is there anyway that I can make it retain the current values but insert and new values that are not in the db?
If not what would be the best way to achieve this?
UPDATE INTO {refocus_candidate_category} SET canid=?, categoryid=? WHERE canid=? AND categoryid=?",array($emailCheck['id'], $id, $emailCheck['id'], $id));
Function:
$catParams = array_merge(array($emailCheck['id']), $fields['Occupation']);
$catPlaceholders = '?'.str_repeat(',?',count($fields['Occupation'])-1);
$catCheck = CMS::selectQuery("SELECT * FROM {table} WHERE canid=? AND categoryid IN (".$catPlaceholders.")", $catParams);
if($catCheck != FALSE)
{
for($i=0; $i<count($fields['Occupation']); $i++) {
$id = $fields['Occupation'][$i];
CMS::updateQuery("UPDATE INTO {table} SET canid=?, categoryid=? WHERE canid=? AND categoryid=?",array($emailCheck['id'], $id, $emailCheck['id'], $id));
}
echo 'found update';
}
ID Print
$fields['Occupation'][$i] = 1678
It's not clear to me from your question precisely what you mean, but there are a number of alternatives for inserts/updates that deal with missing or already present values.
Firstly, if you just want to insert into mysql and have it either create a new row or replace an existing row (where existing is determined by the primary key matching) use REPLACE INTO instead of INSERT INTO. REPLACE INTO tries an insert, but if the primary key already exists, it turns the query into a DELETE and then retries the INSERT.
If you want to insert a new row but leave an existing row alone if you've already got one, you can either use INSERT IGNORE INTO (which may also fail to insert if you've got your data types or column info wrong...) or INSERT INTO ... ON DUPLICATE KEY UPDATE which allows you to do much finer grained control of how you handle inserts of items that already exist.
There's other options as well, but those are probably the most relevant.
Related
I need a way to check a database if a word is in it already if so then it doesn't have to be pushed to the database if the word isn't in it yet then it has to be pushed into it.
It's a MYSQL database and I have to do it in PHP this is what I got so far.
$result = array_count_values(explode(" ", $filter));
arsort($result);
foreach ($result as $word => $frequency)
{
if (!in_array($word, [" ", ""]))
query("words", "INSERT INTO Woord (woord) VALUE (?)",[$word], false);
}
query("words" "SELECT WHERE")
You have 2 options:
REPLACE
REPLACE INTO table
SET column = 'example'
This will overwrite if the record exists and if not it will create it.
INSERT IGNORE
INSERT IGNORE INTO table
SET column = 'example'
This will ignore the query if already exists and if not it will create it.
Your php query should look like this:
"INSERT IGNORE INTO ID142118_ascii.Woord (woord) VALUES (".$word.")"
put a unique constraint on the column "woord" in the table.
Then you can let your php script insert as many duplicate words as you want to, it will simply fail.
you could either add a part "ignore duplicate" in your query or just ignore the error you will get.
I thinks that will be easiest to do.
edit:
btw I can think of a lot of words containing serveral of the character you are stripping: "foto's", "zee-eend" etc
--
how to make a unique index:
ALTER TABLE asciiwoorden
ADD UNIQUE INDEX somename (Woord);
I'm using PHP in order to create a website where managers have access and review forms that employees have submitted. In the reviewing PHP file, I have created two buttons which basically approve or disapprove the form. After they click on one of the buttons, they are being redirected to another PHP file which actually inserts into the MySQL Database a change in a column I named 'processed'. It changes 0 which is unprocessed to 1, which is processed. The table I am referring to has columns such as formid, fullname, department and other job related stuff, as well as the 'processed' column which allows the managers to see if there is a pending form to be reviewed.
My problem is that I have no idea how to actually allow MySQL to find the proper row and change only the cell with the name 'processed' from 0 to 1 without having to insert every cell again. Here's what I have tried till now:
$id = $_SESSION[id];
$fullname = $_SESSION[fullname];
$teamformid = $_SESSION[teamformid];
if (isset($_POST['approved'])) {
$sql = "INSERT INTO carforms (processed) where aboveid='$id' and processed='0' and teamformid=$teamformid
VALUES ('0')";
}
else if (isset($_POST['disapproved'])) {
//todo
}
How do I tell SQL to only find the specific row I want and change only one column which is processed?
Also, do I always have to type every column name when I use the INSERT INTO command?
Thanks in advance.
Use the Below code it'll work for you.
$id = $_SESSION[id];
$fullname = $_SESSION[fullname];
$teamformid = $_SESSION[teamformid];
if (isset($_POST['approved'])) {
$sql = "UPDATE `carforms` SET processed = '1' WHERE `aboveid` = '".$id."' AND `teamformid` = '".$teamformid."'";
}
Try:
"UPDATE carforms SET processed = 1 WHERE aboveid = $id AND teamformid = $teamformid"
From what I have interpreted from your question, it seems like you need to use the MySQL UPDATE command. This will update any existing rows.
For example, let's say you have a table called 'forms', consisting of a Primary Key 'form_id' and a field named 'processed'.
If we want to change the value of 'processed' to '1', we would run...
UPDATE forms SET processed = 1 WHERE form_id = [whatever number the form is];
Obviously this only works where the form (with a form_id) exists already
There is no "INSERT...WHERE" in SQL.
To change an existing record there are 2 options, REPLACE or UPDATE. The former will create the record if it does not already exist and has similar syntax to INSERT. UPDATE uses the WHERE clause to identify the record(s) to be changed.
Using REPLACE is tricky. It needs to work out whether it should INSERT a new record or UPDATE an existing one - it does this by checking if the data values presented already exist in a unique index on the table - if you don't have any unique indexes then it will never update a record. Even if you have unique indexes just now, the structure of these may change over time as your application evolves, hence I would recommend NOT using REPLACE for OLTP.
In your question you write:
where aboveid='$id' and processed='0' and teamformid=$teamformid
(it would have been helpful if you had published the relevant part of the schema)
'id' usually describes a unique identifier. So there shouldn't be multiple records with the same id, and therefore the remainder of the WHERE clause is redundant (but does provide an avenue for SQL injection - not a good thing).
If the relevant record in carforms is uniquely identifed by a value for 'id' then your code should be something like:
$id=(integer)$id;
$sql = "UPDATE carforms SET processed = $action WHERE aboveid=$id";
But there's another problem here. There are 3 possible states for a record:
not yet processed
declined
approved
But you've only told us about 2 possible states. Assuming the initial state is null, then the code should be:
$action=0;
if (isset($_POST['approved'])) {
$action=1;
}
$id=(integer)$id;
$sql = "UPDATE carforms SET processed = $action WHERE aboveid=$id";
if ($id &&
(isset($_POST['disapproved']) || isset($_POST['approved']))
) {
// apply the SQL to the database
} else {
// handle the unexpected outcome.
}
This question might probably have been asked somewhere but I just can't seem to find it after much searching.
I have a basic question on how I can prevent the last SQL statement in my code below from executing if it caused any row/data in the table to change.
$query = 'SELECT pdt_code FROM `Products`';
$stmt = $con->query($query);
while ($obj = $stmt->fetch()) {
$pdt_code[] = $obj['pdt_code'];
}
$args = implode(',',
array_map(function($el) {
return '('.implode(',', $el).')';
},
array_chunk(array_fill(0, count($pdt_code), '?'), count($pdt_code))
)
);
$query = 'ALTER TABLE `MapProduct` CHANGE product_code product_code SET '.$args.' COLLATE utf8mb4_unicode_ci NOT NULL';
$stmt = $con->prepare($query);
$stmt->execute($pdt_code); // how do I prevent this line from executing if it causes the data in table `MapProduct` to change?
I am trying to execute this from PHP where I query another table for updates to product codes and update the SET() accordingly. However, I had a horrific experience of losing all my data because the update was not properly executed and all the data in product_code got wiped.
Although mysql's SET data type can be used to restrict list of values being entered. However, it is not flexible and requires an alter table to update the list of values. If you frequently have to do this - and if you build a functionality to do that, then you need to do this frequently - then the SET data type is simply not for you.
I would create a separate table for product types and I would simply reference this table with a foreign key from your mapproduct table. This way adding a new product type to the allowed list inly requires an insert statement.
I am refering to this post. I am stuck with a problem I can't resolve. I try to insert multiple rows with a php script into a MySQL database. I don't succeed in updating the whole thing using ON DUPLICATE KEY UPDATE and using a WHERE condition (at the end of the code below) I would like to use to update only an entry has been modified recently:
// for information (used in a foreach loop):
$args[] = '("'.$row['lastname'].'", '.$row['phone'].', "'.$row['lastModification'].'")';
// then:
$stringImplode = implode(',', $args);
// Where I am stuck - WHERE statement:
$sql = $mysqli->query('INSERT INTO table_name '. (lastname, phone, timestamp) .' VALUES '.$stringImplode .'ON DUPLICATE KEY UPDATE lastname=VALUES(lastname), phone=VALUES(phone) WHERE timestamp > VALUES(lastModification);
Everything works fine except I cannot set any WHERE condition at this point that involves multiples entries. Maybe the WHERE statement in this case is not intended to refer to a condition in this statement.
I was told to try with a database procedure using a JOIN statement and a temporary table with first all my entries and then querying some conditions. But I have to admit I don't understand very well how I could leverage such a table to update an other table.
Is there an easy and lovely way to use a "CASE WHEN" or an "IF" statement in this case?
Would something like
INSERT INTO ... ON KEY DUPLICATE UPDATE lastname = VALUES(lastname), phone = VALUES(phone)
CASE WHEN (timestamp > VALUES(lastModification)) THEN do nothing ...
or
...ON KEY DUPLICATE UPDATE... IF (timestamp > VALUES(lastModification)) ...
If anyone could help me, I would be very grateful.
EDIT: Since I will have many variables, could it be used in this way:
INSERT INTO ... ON KEY DUPLICATE UPDATE
IF(timestamp > VALUES(timestamp),
(
name = VALUES(name),
number = VALUES(number),
timestamp = VALUES(timestamp)
....many other variables
),
(
name = name,
number = number,
timestamp = timestamp
....many other variables)
)
You can use simple IF function in value like this:
INSERT INTO ... ON KEY DUPLICATE UPDATE
name = VALUES(name),
number = VALUES(number),
timestamp = IF(timestamp > VALUES(timestamp), VALUES(timestamp), timestamp)
If condition is not met, it will update timestamp with the same timestamp which already exists. It does not matter, because update to same values is optimized before it is even executed, so MySQL will not make real update. You should not afraid of some performance penalty.
EDIT:
IF works likes this:
IF(condition, returned when true, returned when false)
Maybe you need to switch those two arguments to fit your condition like you want.
i am using mysql_affected_rows() to check if i have to enter new record or update existing, but the problem is if the user tries to enter exactly same data as record which already exists it runs insert into.
$result = mysql_query("update Data set Score='$score',Comment='$_POST[Comments]' where Date='$_POST[forDay_3]-$_POST[forDay_1]-$_POST[forDay_2]' AND User='$_POST[UserID]';");
$last = mysql_affected_rows();
if ($last==0) {
$result1 = mysql_query("INSERT INTO Data (User,Date,Score,Comment) VALUES ('$_POST[UserID]','$_POST[forDay_3]-$_POST[forDay_1]-$_POST[forDay_2]','$score','$_POST[Comments]')");
what should i do to avoid redundant entries
You could parse mysql_info() output (but the solution itself will be affected by race condition issue)
You could create unique key User + Date and end up with a single query using ON DUPLICATE KEY UPDATE syntax:
INSERT INTO `Data` (User,Date,Score,Comment)
('$_POST[UserID]','$_POST[forDay_3]-$_POST[forDay_1]-$_POST[forDay_2]','$score','$_POST[Comments]')
ON DUPLICATE KEY UPDATE Score='$score',Comment='$_POST[Comments]'
some solutions:
add another query to see if data exists, and then decide if you want to do some action (update/delete) or nothing.
add a 'modified' column with type "TIMESTAMP" and make it on update - CURRENT_TIMESTAMP
i'd go with first option.
btw, you should escape your post data (mysql_real_escape_string) to prevent injects or malformed query string
You may get the number of affected rows with FOUND_ROWS() instead of mysql_affected_rows(). The latter counts the not modified rows as well.
$result = mysql_query("update Data set Score='$score',Comment='$_POST[Comments]' where Date='$_POST[forDay_3]-$_POST[forDay_1]-$_POST[forDay_2]' AND User='$_POST[UserID]';");
$last = mysql_query("SELECT ROW_COUNT();");
$last = mysql_fetch_array($last);
...
Reference: http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_row-count