How to update many rows with uniqid() making them unique in php - php

I created a new column in mysql, that is going to store a unique value for all of the elements inside the database.
Now I would like to populate all rows with this unique value using uniqid().
But since the function makes use of microtime(), I can't update all rows together.
How could I do it?
$unique_id = uniqid();
$sql = "UPDATE posts SET unique_id = :unique_id";
$stmt = $pdo->prepare($sql);
$stmt->execute(['unique_id' => $unique_id]);
This code updates the same value for all rows.
How can every row be unique?

try with below code
SET #r := 0;
UPDATE posts
SET unique_id = (#r := #r + 1)
ORDER BY RAND();

Try this ,
update posts set unique_id = #i:=#i+1 order by rand();
The numbers will now randomly assigned to rows, but each row has a unique value.

uniqid('', TRUE),
You can use uniqid with the entropy to make it more sensitive in time to narrow down even more the chance of duplicates but keep one thing in mind:
This function does not guarantee uniqueness of return value. Since
most systems adjust system clock by NTP or like, system time is
changed constantly. Therefore, it is possible that this function does
not return unique ID for the process/thread. Use more_entropy to
increase likelihood of uniqueness.
What you can do as well is to put a random prefix like:
uniqid(mt_rand(), TRUE);
That will eliminate every chance to generate a duplicate.
You are going to use a random prefix + entropy sensitivity. The generated value will be unique even if your script runs that fast that the timestamp happens to be the same even in miliseconds.
The problem with your code is that you use uniqid() function one time by assigning it to a variable and from there you get duplicates of course cause you use this variable:
Try this code:
$sql = "UPDATE posts SET unique_id = uuid()";
$stmt = $pdo->prepare($sql);
$stmt->execute();

So after some tries I came across my own solution, using uniqid().
Here's my code, commented:
// Selecting all the posts
$sql = "SELECT id, pro_key FROM posts";
$stmt = $pdo->prepare($sql);
$stmt->execute();
$posts = $stmt->fetchAll();
// Looping through all the results and updating them one by one with a delay of 1 second between the updates
foreach($posts as $post) {
$sql = "UPDATE posts SET unique_id = :unique_id WHERE id = :id";
$stmt = $pdo->prepare($sql);
$stmt->execute(['id' => $post->id, 'unique_id' => uniqid()]);
// delay
sleep(1);
}
Hope this helps.

Related

How run multiple queries in a row

I have a table for storing storing page visit counts. The first statement firs makes a query to get the current stored data, and the second increments the first result and updates the table.
here is an example.
$conn = new PDO(...);
//get current value
$stmt = $conn->query("SELECT counter FROM table");
$newValue = $stmt->fetch(PDO::FETCH_ASSOC);
//increment
$stmt = $conn->prepare("update table set counter = ?");
$stmt->execute(array($newValue));
The above is just an example, But I need an approach where it involves making a single prepare() to count and update the counter by 1, on each page visit.
The following will take the column value and increment itself by one (or whatever you'd like) in a single statement
UPDATE table SET counter = counter + 1
You can simply use this query:
update table set counter = (counter+1)
Please try this :
UPDATE table SET counter = ((SELECT counter FROM table)+1)
I hope this help u :)

Mysql update query, what if value didn't change? how do I check for that?

When executing UPDATE statement, if value is same as new value than rowCount doesn't change. But for purposes of my application this is also a success. So how do I check for successful update no matter if value changed or not?
$stmt = $conn->prepare('UPDATE users SET name = :name WHERE id = :id');
$result = $stmt->rowCount(); // 1
if ($result == 1) {echo "success!";}
You're not executing the query, merely preparing it. So rowCount() will report an invalid number of rows (the one referring to the last executed query), since no rows were affected yet, and the system doesn't know beforehand how many will be, once you execute the prepared statement with specific param values.
You should check for success upon executing the statement. The execute() method will return true if it succeeds and false otherwise. So if execution success is the only thing you need, then you should do it along the lines of:
$stmt = $conn->prepare('UPDATE users SET name = :name WHERE id = :id');
$result = $stmt->execute($params); // <-- execute first!
if ($result) {echo "success!";}
I agree with Legionar. But instead of count I used to add a column that contains the last update time. So that I can use that to get the entries that got updated after a specific time. In this way I able to reduce the number of entries send to client. The final decision is based on your requirement.
$stmt = $conn->prepare('UPDATE users SET name = :name, updateTime = currentTime WHERE id = :id');
$result = $stmt->rowCount(); // 1
if ($result == 1) {echo "success!";}
I think this cant be done normally, but you can use another column for help.
Add column counter to your users table. And then just increase this value on each update.
$stmt = $conn->prepare('UPDATE users SET name = :name, counter = counter + 1 WHERE id = :id');
$result = $stmt->rowCount(); // 1
if ($result == 1) {echo "success!";}
So now, doesnt matter, if value name will change or not, counter will change each time, so it will return each time 1 if successed.
Or also as Damodaran answered, instead of counter you can use current datetime when doing update.

Combine SELECT and UPDATE to avoid duplicate selects

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
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

How to use count in php?

I want to insert data to database. I have a table, named member that has 7 column (ID, User, Password, Address, Phone, Gender, Email). I used count to make auto number like this
$no = "SELECT COUNT(ID)FROM member";
$nors = mysql_query($no);
$nors = $nors + 1;
$query = "INSERT INTO member VALUES (".$nors.",'".$user."','".md5($pass)."','".$name."','".$addr."',".$hp.",'".$gender."','".$email."')";
Why, the result of nors is 6 not 2, although I only have 1 data?
mysql_query returns a result object, not the value. Your query also lacks a needed space between COUNT(ID) and FROM...
$no = "SELECT COUNT(ID) AS count FROM member";
$result = mysql_query($no);
$row = mysql_fetch_object($result);
$nors = $row->count;
You should consider using something more modern like PDO, though, as mysql_* functions have been deprecated and will eventually go away entirely.
edit: #andrewsi noted in the comments that you really should be using MySQL's built-in auto increment functionality for IDs, anyways. Much better than what you're currently doing.
If you're using this to generate the next ID number for a new member, you should look at making ID an auto_increment field instead - as it stands, it's possible that you'll get two members signing up at the same time, and both getting assigned the same ID
Replace this line
$nors = mysql_query($no);
By these lines :
$result_handler = mysql_query($no);
$result = mysql_fetch_array($result_handler);
$nors = $result[0];
If your id field is set to be an auto number you don't need to insert it. MySql will handle that for you. Anytime you add a new row the autonumber is incremented. If you delete a row the autonumber does not decrement.
If you currently only have 1 row but you've added and deleted rows then your insert will produce a row with an ID that is not consecutive.

Setting status of other rows after INSERT

Hey, I have a field called STATUS and it is either 1 to show or 0 to hide. My code is below. I am using an edit in place editor with jQuery. Everytime you update it creates a new ROW which I want, but I want only the new one to have STATUS = 1 and the others to 0. Any ideas on how I would do that?
<?php
include "../../inc/config.inc.php";
$temp = explode("_", $_REQUEST['element_id'] );
$field = $temp[0];
$id = $temp[1];
$textboxval = stripslashes(mysql_real_escape_string(preg_replace('/[\$]/',"",$_REQUEST["update_value"])));
$query = "INSERT INTO notes ($field,status,date,c_id) VALUES ('$textboxval','1',NOW(),'$id')";
mysql_query($query);
echo($_REQUEST['update_value']);
?>
I am not sure exactly what you mean - do you want to make all the entries except the new one have status = 0? If so, just issue an update before the insert:
UPDATE notes SET status = 0
However, I should also note that you have a potential SQL injection to worry about. By stripping slashes after applying "mysql real escape string", you are potentially allowing someone to put text in your SQL statement that will execute an arbitrary SQL statement.
Something like this, sorry for the post before, I mis read it the first time then went back:
<?php
include "../../inc/config.inc.php";
$temp = explode("_", $_REQUEST['element_id'] );
$field = $temp[0];
$id = $temp[1];
$textboxval = mysql_real_escape_stringstripslashes((preg_replace('/[\$]/',"",$_REQUEST["update_value"])));
// set older entries to 0 - to not show but show in history
$hide_notes = "UPDATE notes SET status = 0";
mysql_query($hide_notes);
// add new entry with status of 1 to show only latest note
$query = "INSERT INTO notes ($field,status,date,c_id) VALUES ('$textboxval','1',NOW(),'$id')";
mysql_query($query);
echo($_REQUEST['update_value']);
?>
i just ran in to a problem I didn't of the set up of my table doesn't allow me to show more than one client a time and i will be having numerous clients, my bad on planning ha
You really want to get the ID of the newly generated row and then trigger an UPDATE where you all rows where the ID is not the new row, e.g.
UPDATE notes SET status = 0 WHERE id != $newly_generated_id
If the ID column in your table is using AUTO_INCREMENT you can get its ID via "SELECT LAST_INSERT_ID()" and then use the return value in that statement in your UPDATE statement.
Pseudo code:
$insert = mysql_query("INSERT INTO ...");
$last_id = mysql_query("SELECT LAST_INSERT_ID()");
$update = mysql_quqery("UPDATE notes SET status = 0 WHERE id != $last_id");
The only caveat to this approach is where you might have a brief moment in time where 2 rows have status=1 (the time between your INSERT and the UPDATE). I would wrap all of this in a transaction to make the whole unit more atomic.

Categories