MySql: Lock with no effect? - mysql

I have a table "offers" which contains "orders" as well. An offer can be changed into a "order" by adding a unique incremental order-number.
I do:
$DB->Sql("SELECT GET_LOCK('ORDERNO')");
$n = $DB->resultSql("SELECT max(orderno) FROM orders");
$n += 1;
$DB->Sql("UPDATE orders SET orderno=".$n." WHERE id=".$actualId);
$DB->Sql("SELECT RELEASE_LOCK('ORDERNO')");
But resently, I got two identical order-numbers.
I want to avoid using
SELECT max(orderno) FOR UPDATE
because this blocks the whole table, and the orderno is ONLY set in this part of the code so my idea was to use LOCKS to make everything faster.
Any idea why it was possible to get the same number twice?

You can use a single update statement:
update orders t
cross join (select max(orderno) as maxno from orders) x
set t.orderno = x.maxno + 1
where id = ?;
Demo: http://rextester.com/GEJHX43916
This way you don't need to lock anything manually.

Related

MySQL Query gets too complex for me

I'm trying to write a MYSQL Query that updates a cell in table1 with information gathered from 2 other tables;
The gathering of data from the other 2 tables goes without much issues (it is slow, but that's because one of the 2 tables has 4601537 records in it.. (because all the rows for one report are split in a separate record, meaning that 1 report has more than 200 records)).
The Query that I use to Join the two tables together is:
# First Table, containing Report_ID's: RE
# Table that has to be updated: REGI
# Join Table: JT
SELECT JT.report_id as ReportID, REGI.Serienummer as SerialNo FROM Blancco_Registration.TrialTable as REGI
JOIN (SELECT RE.Value_string, RE.report_id
FROM Blancco_new.mc_report_Entry as RE
WHERE RE.path_id=92) AS JT ON JT.Value_string = REGI.Serienummer
WHERE REGI.HardwareType="PC" AND REGI.BlanccoReport=0 LIMIT 100
This returns 100 records (I limit it because the database is in use during work hours and I don't want to steal all resources).
However, I want to use these results in a Query that updates the REGI table (which it uses to select the 100 records in the first place).
However, I get the error that I cannot select from the table itself while updateing it (logically). So I tried selecting the select statement above into a temp table and than Update it; however, then I get the issue that I get to much results (logically! I only need 1 result and get 100) however, I'm getting stuck in my own thougts.. I ultimately need to fill the ReportID into each record of REGI.
I know it should be possible, but I'm no expert in MySQL.. is there anybody that can point me into the right direction?
Ps. fixing the table containing 400k records is not an option, it's a program from an external developer and I can only read that database.
The errors I'm talking about are as follows:
Error Code: 1093. You can't specify target table 'TrialTable' for update in FROM clause
When I use:
UPDATE TrialTable SET TrialTable.BlanccoReport =
(SELECT JT.report_id as ReportID, REGI.Serienummer as SerialNo FROM Blancco_Registration.TrialTable as REGI
JOIN (SELECT RE.Value_string, RE.report_id
FROM Blancco_new.mc_report_Entry as RE
WHERE RE.path_id=92) AS JT ON JT.Value_string = REGI.Serienummer
WHERE REGI.HardwareType="PC" AND REGI.BlanccoReport=0 LIMIT 100)
WHERE TrialTable.HardwareType="PC" AND TrialTable.BlanccoReport=0)
Then I tried:
UPDATE TrialTable SET TrialTable.BlanccoReport = (SELECT ReportID FROM (<<and the rest of the SQL>>> ) as x WHERE X.SerialNo = TrialTable.Serienummer)
but that gave me the following error:
Error Code: 1242. Subquery returns more than 1 row
Haveing the Query above with a LIMIT 1, gives everything the same result
Firstly, your query seems to be functionally identical to the following:
SELECT RE.report_id ReportID
, REGI.Serienummer SerialNo
FROM Blancco_Registration.TrialTable REGI
JOIN Blancco_new.mc_report_Entry RE
ON RE.Value_string = REGI.Serinummer
WHERE REGI.HardwareType = "PC"
AND REGI.BlanccoReport=0
AND RE.path_id=92
LIMIT 100
So, why not use that?
EDIT:
I still don't get it. I can't see what part of the problem the following fails to solve...
UPDATE TrialTable REGI
JOIN Blancco_new.mc_report_Entry RE
ON RE.Value_string = REGI.Serinummer
SET TrialTable.BlanccoReport = RE.report_id
WHERE REGI.HardwareType = "PC"
AND REGI.BlanccoReport=0
AND RE.path_id=92;
(This is not an answer, but maybe a pointer towards a few points that need further attention)
Your JT sub query looks suspicious to me:
(SELECT RE.Value_string, RE.report_id
FROM Blancco_new.mc_report_Entry as RE
WHERE RE.path_id=92
GROUP BY RE.report_id)
You use group by but don't actually use any aggregate functions. The column RE.Value_string should strictly be something like MAX(RE.Value_string) instead.

Trying to update table with values from second table MySQL results in unending "running query"

I'm trying to replace null values in one table with values from a second table, based on matches from other columns in both tables. While the code does not result in error, it does not stop running, producing an unending "running query" signal. code is here
UPDATE pl_building b
INNER JOIN pl_grt t
ON b.INST = t.inst
SET b.Utuition=t.tuition
WHERE b.UtUITION = 0;
You should not update on join tables.
I am not sure what field you want to update, but your SQL should look like this:
UPDATE pl_building b
SET b.Utuition= (select t.tuition from pl_grt t ON b.INST = t.inst)
WHERE b.UtUITION = 0;
Make sure :
1) You have an index on t.inst table column and maybe also on b.UtUITION
2) Relationship between b.INST = t.inst is unique. Never returns more than 1 row.

How to copy 3 columns from one table into another in mysql

I have two tables and both include 2 columns, sureness and kindness and and they are related to each other by dataitemID and id. Just to show you the structure I will put 2 selects that I got from database:
SELECT ID,sureness,kindness FROM omid.tweet ;
SELECT ID,DataitemID,sureness,kindness FROM omid.entity_epoch_data ;
and I want to copy all value of sureness and kindness in omid.tweet into entity_epoch_data where entity_epoch_data.entityID is equal to entityID coming from entity_relation where tweet.ID =entity_relation.ID
I want just to do it in mysql rather than reading the whole table in java and updating the database in the loop but I am so confused. How can I do that?I appreciate any help:)
Update:
I wrote the code as follow but it does not work:
update tweet, entity_epoch_data
set entity_epoch_data.sureness= tweet.sureness,
entity_epoch_data.kindness = tweet.kindness ,
entity_epoch_data.calmness = tweet.calmness ,
entity_epoch_data.happiness = tweet.happiness
WHERE entity_epoch_data.EntityID in(
SELECT EntityID FROM omid.entity_dataitem_relation
INNER JOIN omid.tweet t ON entity_dataitem_relation.DataitemID = t.ID)
It's actually pretty straight forward. The UPDATE clause works like a JOIN and then use SET to set the values
UPDATE tweet INNER JOIN entity_epoch_data
ON tweet.id = entity_epoch_data.id
SET entity_epoch_data.sureness= tweet.sureness,
entity_epoch_data.kindness = tweet.kindness

MySQL - Update where fields are the same

The title probably doesn't say much useful, so I'll explain. Basically I have a first query:
UPDATE sales_records
INNER JOIN (SELECT buyer_full_name, buyer_address_1
FROM sales_records
GROUP BY buyer_full_name, buyer_address_1
HAVING COUNT(*)>1) multiorder
ON sales_records.buyer_full_name = multiorder.buyer_full_name
AND sales_records.buyer_address_1 = multiorder.buyer_address_1
SET processed=1
WHERE sales_records.buyer_full_name<>''
AND sales_records.buyer_address_1<>''
So the above sets everyone who has made more than one order as processed=1. However, in the same table there are parts of the order which do not have a buyer_address_1 or a buyer_full_name but do have the same sales_record_number field. I need to update the remaining ones with the same sales_record_number to processed=1 too.
This is what I've tried (amongst other similar variations) but it doesn't work:
UPDATE sales_records
WHERE sales_record_number=(SELECT sales_record_number
FROM ebay_sales_records
WHERE processed=1)
AND processed=1
Any ideas?

Update mysql cell after fetching related cell value via select?

SQL:
$mysqli->query("UPDATE results
SET result_value = '".$row[0]['logo_value']."'
WHERE logo_id = '".$mysqli->real_escape_string($_GET['logo_id'])."'
AND user_id = '".$user_data[0]['user_id']."'");
This results table also contains result_tries I'd like to fetch before doing update, so I can use it to modify result_value... Is there a way to do it in a single shot instead of first doing select and than doing update?
Is this possible?
Basically:
UPDATE results SET result_value = result_value + $row[0][logo_value]
for just a simple addition. You CAN use existing fields in the record being updated as part of the update, so if you don't want just addition, there's not too many limits on what logic you can use instead of just x = x + y.