mysql - update two records at once - php

Using PHP's msqli is it possible to update two records with one query?
First I do a SELECT to check that $pay_user has enough game currency in his account, if he does then I do the following...
My update query is:
"UPDATE account SET money= money - ".$money." WHERE User_id=".$pay_user
"UPDATE account SET money= money + ".$money." WHERE User_id=".$recieve_user
It is transactional to stop dirty read's.
I was hoping to save on a query and call it as one... is it possible?

Since the two where clauses are not the same, you cannot combine these queries into one statement.
You can mark it as a TRANSACTION so they both execute at the same time.

refer to http://dev.mysql.com/doc/refman/5.0/en/update.html
code sample
update account a1, account a2
set a1.money = a1.money - $money , a2.money = a2.money + $money
where a1.user_id = $pay_user and a2.user_id = $recv_user

I recommend using a stored procedure to do this. it will be one call from php, and if it fails in the middle the SP should issue a rollback.

Related

MySql implementing increase and descrase fields and get result

In my application i want to implementing this mySql command as a single command to use that and get result on time without use any other command by programing out of this box such as PHP or etc,
what i want to implementing action:
check user money
IF user has money then
decrease money from himself
AND
increase money of other user
RETURN result
ELSE
RETURN result as false
this command is my implementation but its not correct
SELECT *, (case when (money >= 200)
THEN
if(
(update money_repositories set money = money-200 where userId = 1)
AND
(update money_repositories set money = money+200 where userId = 34)
) as state
ELSE
false
END)
as state from money_repositories where userId = 1;
how can i fix this command? Thank you very much
What we have here is a financial transaction. It would be horrible if the money was deducted from the first user and not second user. Is it a coincidence then that mysql has something called a transaction?
You cannot have an update inside a select. You need to have two different update statements here. First to deduct from user1, second to credit into user2's account. Transactions ensure that both operations succeed together or the first query is rolled back preserving user1's money.
The other aspect of transactions ensure's that another thread does not make a similiar modification changing the balance between the two update queries.

PHP Incrementing Max ID

Hello so I have a code that will check if a username exists and if yes, I want to set the variable $var to the present accountID of the existing username. If the username doesn't exist, I want the MAX of the latest accountID to increment. Here is my code:
$checkUname = $conn->prepare("SELECT accountID from accounts WHERE username=?");
$checkUname->execute(array($_POST['txt_un']));
$row = $checkUname->fetch(PDO::FETCH_ASSOC);
if($row > 0) {
$var = $row['accountID'];
} else {
$getMax = $conn->query("SELECT MAX(accountID) as maxAccountID FROM accounts");
$row = $getMax->fetch(PDO::FETCH_ASSOC);
$maxID = $row['maxAccountID'];
$maxID++;
$var = $maxID;
}
$UpdateTable = $conn->prepare("UPDATE otherTable SET someField=? WHERE otherTableID=?");
$UpdateTable->execute(array($var, $_POST['tableID']));
Now my problem here is, what if 2 or more users will click and run the code above at the same time? Will there be issues on the incrementing ID?
You could use this query to get data at once
IF EXISTS (SELECT accountID from accounts WHERE username=?) THEN
SELECT accountID from accounts WHERE username=?;
ELSE
SELECT MAX(accountID) as maxAccountID FROM accounts;
END IF;
That's why you should have accountID to be an autoincrement column https://dev.mysql.com/doc/refman/5.0/en/example-auto-increment.html
Then you can use LAST_INSERT_ID() to get the id of the inserted user. The page above have a link to this function.
PHP have specific functions to use LAST_INSERT_ID(), each library have its specific function:
PDO: http://php.net/manual/en/pdo.lastinsertid.php
MySQLi: http://php.net/manual/en/mysqli.insert-id.php
MySQL: http://php.net/manual/en/function.mysql-insert-id.php
Here is some extract from this link:click me
It is not exactly what you need, but it has an approach to deal with such problems. And it impies that you are using MySQL InnoDB. If you use MyISAM or MariadDB the solution might be different.
Extract:
Let us look at another example: We have an integer counter field in a table child_codes that we use to assign a unique identifier to each child added to table child. It is not a good idea to use either consistent read or a shared mode read to read the present value of the counter because two users of the database may then see the same value for the counter, and a duplicate-key error occurs if two users attempt to add children with the same identifier to the table.
In this case, there are two good ways to implement reading and incrementing the counter:
First update the counter by incrementing it by 1, and then read it.
First perform a locking read of the counter using FOR UPDATE, and then increment the counter.
The latter approach can be implemented as follows:
SELECT counter_field FROM child_codes FOR UPDATE;
UPDATE child_codes SET counter_field = counter_field + 1;
A SELECT ... FOR UPDATE reads the latest available data, setting exclusive locks on each row it reads. Thus, it sets the same locks a searched SQL UPDATE would set on the rows.
The preceding description is merely an example of how SELECT ... FOR UPDATE works. In MySQL, the specific task of generating a unique identifier actually can be accomplished using only a single access to the table:
UPDATE child_codes SET counter_field = LAST_INSERT_ID(counter_field + 1);
SELECT LAST_INSERT_ID();
The SELECT statement merely retrieves the identifier information (specific to the current connection). It does not access any table.
In General No Problem . why?
It depends on so many factors starting from the ability of DB for performing such queries , the serer processing ,internet connection etc ...
go through links below to get real and specific info
How many MySql queries/second can be handled by a server?
http://yoshinorimatsunobu.blogspot.com/2010/10/using-mysql-as-nosql-story-for.html
Important :
What is PDO?
PHP Data Objects, or PDO, is a database abstraction layer specifically for PHP applications. PDO provides a consistent API for your PHP application regardless of the type of database server your application will connect to. In theory, if you are using the PDO API, you could switch the database server you used, from say Firebird to MySQL, and only need to make minor changes to your PHP code.
Other examples of database abstraction layers include JDBC for Java applications and DBI for Perl.
While PDO has its advantages, such as a clean, simple, portable API, its main disadvantage is that it doesn't allow you to use all of the advanced features that are available in the latest versions of MySQL server. For example, PDO does not allow you to use MySQL's support for Multiple Statements.
http://php.net/manual/en/mysqli.overview.php

Slow Oracle query

I am building a web application for a customer and I have a problem with a particular SQL query.
The query is:
select order_header.order_no,
order_header.purchase_order_no,
order_header.entry_date,
order_header.delivery_date,
order_totals.total_quantity
from order_header,
order_totals
where order_header.order_no = order_totals.order_no
I have done some troubleshooting and this:
where order_header.order_no = order_totals.order_no
is the problem. The SQL query with this line takes 35 seconds (causes DataTables to even time out at times) and without it it is instant.
So, I know the problem but I'm not a DBA so don't know the solution.
It's not my database, so the solution I need to send to the DBA to sort so I can continue with my job. Something like
"Hey, would you mind doing A on B table so that C speeds up?"
I just don't know what actually needs to be done!
First add an index on both order_header.order_no and order_totals.order_no and check that both the columns are of the same type.
For other optimizations we should talk about the data.
Don't forget to update the statistics
Ask your DB to
add an index on the order_no column in both order_header and order_total
That should help with your current problem. Also, look up JOIN and change your query to use the JOIN syntax.
select order_header.order_no,
order_header.purchase_order_no,
order_header.entry_date,
order_header.delivery_date,
order_totals.total_quantity
from order_header
join order_totals ON order_header.order_no = order_totals.order_no

updating an empty date/time field and a status(varchar) field simultaneous with a single query in mysql

im designing a web portal to monitor the distribution of voters cards and im having a little issue with my database query. i want to be able to track the exact time each card is issued using the mysql built in NOW() statement by issuing a query that will save update the date and time field and simultaneously update another field on the same row in my database but my query doesn't seem to work. please i need help, check out my sql query below
$query = "UPDATE PVC_Issuance SET current_status = 'collected', date_&_time_issued = NOW() WHERE VIN = '$VIN'";
note this code works if i take of "date_&_time_issued = NOW()" from the query but gives no output if i include it
please i need help asap.... thanks in advance
if the Column date_&_time_issued Type is DATETIME this is maybe the problem so you should change it to VARCHAR or INT

Multiple update to the same row in database

I'm making a Billing system with some friends, it works this way:
The customers make calls.
The customers hangup the call.
The price of the call is calculated.
The price of the call is reduced from the customer's credit.
We decided to make the following:
Get the user's balance and store it in a variable, $balance, after do a $balance = $balance - $callprice, and finally update the database.
The problem is that the customer can make simultaneous calls, and if two calls finish at the same time, and one of them gets the value on the database before the other script had updated the new balance... one of the calls will be lost. I'm using php.
Any idea how can I do it?
Thanks, and sorry, I have a poor English...
The problem is it looks like you're trying to use two SQL statements to update the user's balance: One to SELECT the user's balance, then another to UPDATE the user's balance after the balance is subtracted using PHP.
You could do it all in one operation and eliminate the possibility of race-conditions:
UPDATE users
SET balance = balance - <callprice here>
WHERE user_id = <user_id here>

Categories