سؤال

I am tring to re-index a table with a function inside php/joomla ... it does nothing. I can not make the entire set of slq commands wihtin one string either.

function ReNumberID($TABLENAME ,$COLUMNNAME) {
$sql = "set @a=0; " ;
$db = JFactory::getDbo();    

$query = $db->getQuery(true);   

$db->setQuery($sql);
$db->execute();
$sql2 = "UPDATE `".$TABLENAME."` SET `".$COLUMNNAME."`=(@a:=@a+1); " ;

$db->setQuery($sql2);
$db->execute();
$sql3 = "SELECT * FROM  `".$TABLENAME."` WHERE 1" ;

$db->setQuery($sql3);
$db->execute(); 
$newindexnumber = $db->getNumRows();
$newindexnumber++ ;
$sql4 = "ALTER TABLE `".$TABLENAME."` auto_increment = ".$newindexnumber." ;";

$db->setQuery($sql4);
$db->execute();
}
هل كانت مفيدة؟

المحلول

First of all, I'd recommend that you check each of your queries to see whether they succeed, and how many rows are affected. You are currently calling execute() and trusting that something actually happened. Who knows if you spelled a column name wrong or got a privilege error or something.

Second, you should make sure you are applying the update in order from the current low id number ascending. Because you could easily cause an error. Here's an example:

mysql> create table bar (id int primary key, x int) engine=myisam;
mysql> insert into bar (id) values (1), (5), (7), (2);
mysql> select * from bar;
+----+------+
| id | x    |
+----+------+
|  1 | NULL |
|  5 | NULL |
|  7 | NULL |
|  2 | NULL |
+----+------+
mysql> set @a := 0;
mysql> update bar set id = (@a:=@a+1);
ERROR 1062 (23000): Duplicate entry '2' for key 'PRIMARY'

The reason is that id 1 is set to 1, then id 5 is set to 2, which conflicts with the fourth row.

mysql> update bar set id = (@a:=@a+1) order by id;
Query OK, 3 rows affected (0.00 sec)
mysql> select * from bar;
+----+------+
| id | x    |
+----+------+
|  1 | NULL |
|  3 | NULL |
|  4 | NULL |
|  2 | NULL |
+----+------+

That at least worked. I never would have known about the duplicate key error if I hadn't checked for errors.

By the way, you can just set ALTER TABLE ... AUTO_INCREMENT=0 and the table will automatically adjust it to the max(id)+1.


But here's my stronger recommendation:

You don't need to renumber the auto-increment key. The primary key must be unique, but it's not required to be consecutive.

It's normal to have gaps. This happens when an INSERT fails, or you DELETE a row, or if you INSERT but then roll back.

You can get problems if you renumber the primary key of rows throughout your table. For instance, if your application communicated outside the database, external systems may have a record of an entity by the old id.

Example: abusive user 1234 harasses other users and gets himself banned and his account shut down and deleted. Then you renumber all the id's and allocate 1234 to another new user. The next day, a lawyers shows up and serves you with a civil complaint against user 1234. The poor new user is blamed for something someone else did.

I wrote about this in my book, SQL Antipatterns Volume 1: Avoiding the Pitfalls of Database Programming. The chapter about this mistake is called "Pseudokey Neat-Freak."

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top