3

i want to combine a SELECT and UPDATE query, to avoid duplicat select of rows.

Here is my example code:

private function getNewRCode() {

    $getrcodesql = "SELECT * FROM `{$this->mysqlprefix}codes` WHERE `used` = 0 LIMIT 1;";
    $getrcodequery = $this->mysqlconn->query($getrcodesql);

    if(@$getrcodequery->num_rows > 0){

        $rcode = $getrcodequery->fetch_array();

        $updatercodesql = "UPDATE `{$this->mysqlprefix}codes` SET `used` =  '1' WHERE `id` = {$rcode['id']};";
        $this->mysqlconn->query($updatercodesql);

        $updateusersql = "UPDATE `{$this->mysqlprefix}users` SET `used_codes` =  `used_codes`+1, `last_code` =  '{$rcode['code']}', `last_code_date` =  NOW() WHERE `uid` = {$this->uid};";
        $this->mysqlconn->query($updateusersql);

        $output = array('code' => $rcode['code'],
                        'time' => time() + 60*60*$this->houroffset,
                        'now' => time()
                        );

        return $output;

    }

}

I would like to execute $getrcodesql and $updatercodesql at once, to avoid that the same code is used for different users.

I hope you understand my problem and know a solution for this.

Greetings, Frederick

Frederick Behrends
  • 3,075
  • 23
  • 47

1 Answers1

2

It's easier if you do it the other way round.
The point is that that your client can generate a unique value before you do the UPDATE and SELECT.

Change the type of your used column to something else, so that you can store a GUID or a timestamp in it, and not just 0 and 1.
(I'm not a PHP/MySQL expert, so you probably know better than me what exactly to use)

Then you can do this (in pseudocode):

// create unique GUID (I don't know how to do this in PHP, but you probably do)
$guid = Create_Guid_In_PHP();

// update one row and set the GUID that you just created
update codes
set used = '$guid'
where id in
(
    select id 
    from codes
    where used = ''
    limit 1
);

// now you can be sure that no one else selected the row with "your" GUID
select *
from codes
where used = '$guid'

// do your stuff with the selected row
Christian Specht
  • 35,843
  • 15
  • 128
  • 182