I have a database with a column representing line numbers. The line numbes correspond to lines in a text area.
Say if I have 10 lines and I go to line 5 and make a new insert, I will now have 11 lines. This means that all the line number values after the insert statement (I have my insert statement working fine) need to be updated by one. Is there a way PHP can update these multiple line number values? I've tried using the LAST_INSERTID() function and adding 1 but with no success.
My attempts:
INSERT INTO Table(LineNumber, Text) VALUES ('LAST_INSERT_ID() + 1', '' )";
Which didn't really make sense
if($linenumber <= mysqli_insert_id() {
$update = "UPDATE Table SET LineNumber='$linenumber' ";
}
I also tried a for loop in the javascript which calls the function to try to carry out an UPDATE statement for each value of Line Number
You can query the database and do a mass update:
UPDATE TABLE *tablename* SET line_number = line_number + 1 WHERE line_number >= 5
and then:
INSERT INTO *tablename* (line_number, ...othervals) VALUES (5, ...othervals)
Related
when doing an sql query from phpmyadmin it works fine but with the script im using i get this error in my php file.
$updatequery = " INSERT INTO emailSave (email, score) VALUES ('$email', '$score') ON DUPLICATE KEY
UPDATE score = '$score'";
the database doenst get updated and i get this error
FAILED 21 : Incorrect integer value: '' for column `id15151883_email`.`emailSave`.`score` at row 1
the table has 4 columns , id auto increment , email unique , score int and time timestamp
As stated in the comments, your $score is empty.
Speaking of, I hope it's sanitized.
Imagine $score being 0'; drop table emailSave;--
Okay so this is my first question and I really have no idea how to ask it so I'm going to try and be as specific as possible. My website is an online game and for user inventories when it inserts a new item into the database
Table name "inventory"
Column names "inv_id", "inv_itemid", "inv_userid", "inv_qty"
and it does not add to the column inv_qty and populate properly instead it creates a new inv_id identifier and row for each item. I was wondering if there was a way for me to create a merge function via php to merge all items with the same inv_itemid and inv_userid while adding to the inv_qty colum and populating the inv_id
In my inventory.php file the inv_id column is used to let the user either equip the item or use it as the main variable.
I have seen this done and have tried many times and I just can't get it to work.
If it were a single key to check then you could have used 'ON DUPLICATE KEY UPDATE' of mysql like the following:
INSERT INTO table(field1, field2, field3, ..)
VALUES (val1, val2, val3, ...)
ON DUPLICATE KEY
UPDATE field3='*'
But in your case there is a combination to consider.
If "inv_id", "inv_itemid", "inv_userid" mathces then UPDATE, otherwise INSERT.
One way to achieve this using only mysql in a single query is to create & use a Stored Procedure.
But using php you can achieve this in 2 query. First query is to determine if the combination exists. Then based on this run the next Insert or Update query.
Please check the following example:
$sql1 = SELECT * FROM inventory WHERE inv_id='$inv_id', inv_itemid='$inv_itemid', inv_userid='$inv_userid'
// Execute $sql1 and get the result.
IF result empty, then INSERT:
$sql2 = INSERT INTO inventory ....
otherwise UPDATE.
$sql2 = UPDATE inventory SET inv_qty=(inv_qty + $update_qty) WHERE inv_id='$inv_id', inv_itemid='$inv_itemid', inv_userid='$inv_userid'
About:
Would there be a way to write a php function at the top of the inventory page for my users to click to merge them
Please check with the following php function.
By calling with param: UserID, it will create a new entry with sum of the inv_qty, for each (inv_itemid + inv_userid) combination and removes the previous duplicate entries of (inv_itemid + inv_userid) leaving the newly enterd: (inv_itemid + inv_userid + (SUM of inv_qty)).
Important, please keep a back up of the DB Table Data before running the function.
Please check the comments in the function and update where necessary based on your system, Like getting the last inserted inv_id.
function merger_fnc($user_id) {
// For Each Combination of: inv_itemid + inv_userid
// This function will Insert a new row in the inventory with the SUM of inv_qty
// And then will remove the previous single rows of: inv_itemid + inv_userid + inv_qty
// First get the distinct Items of the User(by UserID);
$inv_itemids = $db->query("SELECT DISTINCT(inv_itemid) FROM inventory WHERE inv_userid=".$user_id);
// Here $inv_itemids will hold all the distinct ItemIDs for the UserID;
foreach ($inv_itemids as $inv_item) {
// We will Insert A new row which will have the sum of 'inv_qty' for the inv_userid & inv_itemid;
$inv_itemid = $inv_item['inv_itemid'];
// I am not sure what type of result set your $db->query(...) returns. So I assumed it is associative array.
// If the result is an Array of objects, then please use: $inv_itemid = $inv_item->inv_itemid;
$insert_sql = "INSERT INTO inventory (inv_itemid, inv_userid, inv_qty) VALUES ('".$inv_itemid."', '".$user_id."', (SELECT SUM(inv_qty) FROM FROM inventory WHERE inv_userid=".$user_id."))";
$inv_itemids = $db->query($insert_sql);
$inserted_new_inventory_id = $db->insert_id;
// Please check the appropriate method for it in your $db class here.
// In mysqli, it is: mysqli_insert_id($db_conn); In PDO it is: $db_conn->lastInsertId();
// Last we remove the previous data of combination(inv_userid & inv_itemid) but leaving our last inserted row.
$delete_sql = "DELETE FROM inventory WHERE inv_id!='".$inserted_new_inventory_id."' AND inv_userid='".$user_id."' AND inv_itemid='".$inv_itemid."'";
$db->query($delete_sql);
}
}
If getting the last inserted inv_id is troublesome from $db(like inv_id is not defined as key in the table), you can try another approach:
Do another query and save the previous inv_id in an array, before the insertion.
After the insertion of the new entry with sum of qty, run a delete query to delete the previous single qty entries, like the following:
DELETE FROM inventory WHERE inv_id IN (3, 4, 7,...)
Here (3, 4, 7,...) are the previous inv_id for (inv_itemid + inv_userid) combination.
I have the following query:
$year = 2019;
$month = 6;
$stmt = $db->prepare('INSERT INTO officeRechNr (jahr,monat,zahl) VALUES (?,?,1) ON DUPLICATE KEY UPDATE zahl = LAST_INSERT_ID(zahl+1)');
$stmt->bind_param('ii', $year, $month);
$stmt->execute();
echo $db->insert_id;
echo '|';
$sql = 'SELECT LAST_INSERT_ID() as number';
$result = $db->query($sql);
$row = $result->fetch_assoc();
echo $row['number'];
echo '<br>';
The table officeRechNr has the unique primary index ['jahr','monat'] and zahl is an index with autoincrement.
If the table officeRechNr is empty, and I execute the code 3 times, then the output is
1|0
2|2
3|3
...
Why is LAST_INSERT_ID() zero after insert, but correct after upgrade?
How do I need to change my query, so that both functions output the same number (1) after insert?
Edit: The purpose of the code is that I need for each invoice that is created in a specific year and month a third unique ascending number. So for example if we have 7 invoices in the year 2015 and month May (3),then I would have the folloing numbers
2015-3-1
2015-3-2
2015-3-3
2015-3-4
2015-3-5
2015-3-6
2015-3-7
So in the row in the database I have stored the current invoice number and with the SQL command presented above I can get the next number. The only reason why the column zahl is an autoincrement field is that the number is returned by insert_id (see https://dev.mysql.com/doc/refman/5.7/en/getting-unique-id.html). Its also necessary to get it through insert_id in case that people create simultaneously invoices.
The problem is that LAST_INSERT_ID(...); with an argument doesn't return the generated ID but instead set the given value in the "memory" of LAST_INSERT_ID() and returns it. So, in your first execution no auto incremented ID was generated (you provided the value by yourself) and LAST_INSERT_ID() return 0. In your following executions you save the value next+1 in the internal storage of LAST_INSERT_ID(), which returns the value. This behavior is described in the MySQL in 12.14 Information Functions:
If expr is given as an argument to LAST_INSERT_ID(), the value of the argument is returned by the function and is remembered as the next value to be returned by LAST_INSERT_ID().
In fact, you can skip the LAST_INSERT_ID() call and work without it.
INSERT INTO
officeRechNr (jahr,monat,zahl)
VALUES
(?,?,1)
ON DUPLICATE KEY UPDATE zahl = zahl+1
This will insert the row (with the given value) or increase the counter.
If you want the current counter for a given year and month you run a simple SELECT statement. Keep in mind that you might need transactions or locks because a different client could increase the counter before you fetched it with the SELECT statement.
I have a script always verifies that the row exists or not, depending on adjusts to the event.
For example:
if(exists($row)){
// update
}else{
// insert
}
Insert query:
INSERT INTO table (name, value) VALUES
('...', '1'),
('...', '2'),
('...', '3'),
('...', '4'),
('...', '5'),
//...100x
UPDATE QUERY:
UPDATE table
SET value = CASE uuid
WHEN 'x' THEN 1
WHEN 'y' THEN 2
END,
SET value1 = CASE uuid
WHEN 'x' THEN 1
WHEN 'y' THEN 2
END
WHERE uuid IN ('x','y')
Data is quite a lot, and verify that the record exists long enough. Because performs necessary 500x or more.
Exists method:
SELECT id FROM table WHERE uuid=Y;
There is a possibility somehow speed up the script? It is possible to verify existing data added directly to the query?
Can I have just one query CREATE + UPDATE + CHECK EXISTING?
Thanks for help!
Updating and adding data with verification : 27-40 SEC
Updating and adding data WITHOUT verification: 1-5 SEC
EDIT: I'm getting data from another server like json example script:
$data = json_decode($_POST["data"]);
foreach($data as value){
// value is an array
if(exists($value["uuid"])){
$this->appendUpdate($value); // building the update query
}else{
$this->appendInsert($value); // building the insert query
}
}
$this->insert(); // for example: 30 inserts in 1 query
$this->update(); // for example: 500 updates in 1 query
In this table is just 300-2000 rows (I do not understand why it takes so long.)
EDIT2:
This is probably my solution:
INSERT INTO test (uuid, value) VALUES
('aaa', 1),
('bbb', 2),
('ccc', 3)
ON DUPLICATE KEY UPDATE
value = (
IF(uuid='aaa', 4, IF(uuid='bbb', 5, IF(uuid='ccc', 6, value)))
);
I'm going to try to run the brisk server and then touch.
Make sure the column uuid has a unique index and you can do the following query
INSERT INTO table (a,b) VALUES (1,2)
ON DUPLICATE KEY UPDATE b=4;
Something like this:
INSERT INTO table(name,value)
SELECT table2name as name, table2value as value FROM table2
WHERE uuid IS NULL;
Using below query to insert update records:
INSERT INTO table (col_a,col_b,col_c,col_d) VALUES (val_a,val_b,val_c,val_d) ON DUPLICATE KEY UPDATE col_d = VALUES(col_d)
mySQL reports:
1 row affected per insert,
2 rows affected per update,
0 rows affected per duplicate
Followed link : Getting number of rows inserted for ON DUPLICATE KEY UPDATE multiple insert?
but didn't get correct numbers for inserted and updates records.
Is there any way of returning the correct number of inserts, updates and rows skipped (duplicates)?
Thanks overflowers, i worked out on a way.. thanks mitksoft for help, used answer given by a user user3556345 on another post - MySQL on duplicate key update + affected row count
using mysql_info() getting actual records, duplicates and skipped rows and warnings if any
Code below:
list($rec, $dupes, $warns) = sscanf(mysql_info($link), "Records: %d Duplicates: %d Warnings: %d"); // courtesy of user at big lake dot com - php.net
$inserts = $total_rows_affected - ($dupes * 2);
$updates = ($total_rows_affected - $inserts)/2;
$skipped = $rec - ($inserts + $updates);
$total = $rec;