Let's say that I have a table linked to a database like this: http://www.falkencreative.com/forum/records/view.php
How do I make it so that when I delete a record and then add a new one, the new replaces the previously deleted record and has the previously deleted id number instead of the next id?
For example
Red
Blue
Green
click button to delete green.
Red
Blue
click button to add new color.
input orange
Red
Blue
Orange
As it stands, what I'm working with is putting out:
1. Red
2. Blue
4. Orange (What should set this to 3?)
It's probably something simple in terms of the table set up, but I have no idea what to do and I'm pressed for time. Can anyone guide me on what I should do?
You may have 2 options. Either update the same row where the "Green" value was previously. i.e.:
mysql_query("UPDATE table_name SET color = 'orange' WHERE ID = '3'");
or
mysql_query("UPDATE table_name SET color = 'orange' WHERE color = 'green'");
or
whatever your specifiers could be.
this should be from the MySql standpoint the easiest way. Or you can delete it as you initially outlined and re insert new row with mysql_query("INSERT INTO .... but then MySql PK UID will need to be reset i.e.:
mysql_query("ALTER TABLE table_name AUTO_INCREMENT = 1");
which will remove your used PK IDs and renumbers all rows. Or is there an easier solution ?
No, when you delete a database row, if the column have the AUTO_INCREMENT active, it will take the value from a sequence.
If you delete 3, the sequence always start from 3+1.
You can see\set the auto-increment value for example from php myadmin.
I don't know what DBMS are you using, but with oracle you can manipulate the sequence.
So you have various way.
Complicated: When you insert\delete you update the sequence with the triggers
You use 3 coloumn: id, IdToShow, Value.
id is the same of now, you use it with autoinc.
idToShow also is what you show. When you insert you can insert it counting the rows present in the table (you have various ways).
Hope it help.
Your problem is not about database IDs, it's about not understanding the difference between an ID and a line number. They have nothing to do with each other. Just simply output the loop counter ("$i") instead of the ID.
<?php
for ($i = 1; $i <= foo(); $i++) {
print "<tr><td>{$i}</td><td>...</td></tr>\n";
}
?>
I think you want to UPDATE the record, rather than DELETE the old and INSERT a new one.
Edit:
If you want to insert a new record and assign it the next sequential id, use a non-auto_increment column and do this when adding a new record:
INSERT INTO myTable (id, ...) VALUES ( (SELECT MAX(id) + 1 FROM myTable), ...)
I don't have a database handy to test this, but I think it will work. But I'm not sure what will happen when the table is empty. Also this may create a race condition.
Related
Suppose we have a MySQL table (id , name) and a drag-and-drop-enabled list view of the table. User drags 90th row and places it over 10th row. What is the best approach to keep this new sorting?
I do not mean to keep sorting for every use separately
The HTML/JavaScript is not the problem
I have seen some programmers add a weight column to table, setting lower number upper in the table. In my example it will be 1 to 100. The problem is in case of above example (90 to 10) updating 81 rows is required. 90 changes to 10 and each 10 to 89 increments. Is it efficient in MySQL? Is there any better solution?
Another way maybe is saving new order as a string in another table, but in this case we lose MySQL sorting in retrieval phase!
I remember when we learned trie tree structure in university as an
indexing tool, we said wow! Even when we took advantage of every
single bit of a byte, 1.5 GB of pure text data stored in less than
500KB!!! So right now I still search to find a better answer!
Even programming languages when updating indexes for an array that had an object added in a previously occupied index adds one to each index.
You're going to have to end up updating the index for every single row.
The cleanest way to do that however would be something like this (where people is a non trivial table of course):
UPDATE people
SET index = index + 1
WHERE index BETWEEN $newIndex AND $oldIndex;
depending on your database, between might include or exclude the high and low bound numbers. Just make sure you know how it treats them!
Rather than adding a weight column to the MYSQL table, add a next_object column to the table.
It would function kind of like a linked list (if you're familiar with that). Every object entered will point to the next object.
Let's go through the scenario of moving a position 90 object to position 10.
First, you need to update the 89th object so that it now points to the 91st object (the new 90th object)
Then, you need to update the 9th object, and have it point to the 90th object (the new 10th object)
Last, you need to update the 90th object (the new 10th object), and have it point to the 10th object (the new 11th object)
And of course by point I mean, update the next_object field to the object I say I'm pointing to.
What exactly could you put as a value in the next_object field though? Just the object's ID, or something similar.
I just came up with this system as an alternative when I started writing this answer, so I'm not sure it's the most effective way. But hey, updating 3 objects is better than a potential 100,000 (if you had 100,000 objects).
At last, I made the sort by this method: I created a weight column. Each row after insertion gets its id as weight value. It ensures that new row will be at end. weight column is type of FLOAT. Jquery helps to get new position of the row, plus prev() and next() table row. Right new we have three situations that are commented in the fallowing snippet (After retriving IDs from rows and sending Ajax to PHP):
#table of DB
$table = $_POST['table'];
#the id of the row on top
$t = $_POST['t'];
#the id of the row on middle
$m = $_POST['m'];
#the id of the row on bottom
$b = $_POST['b'];
switch ('') {
#top is empty, so the row is droped on top
case $t:
#we set middle weigh 0.5 lower than its bottom
$query = "
UPDATE `$table` m, `$table` b
SET m.`weight` = b.`weight`-0.5
WHERE m.`id` = $m
AND b.`id` = $b
";
break;
#bottom is empty, so the row is droped on the end
case $b:
#we set middle weigh 0.5 upper than its top
$query = "
UPDATE `$table` m, `$table` t
SET m.`weight` = t.`weight`+0.5
WHERE m.`id` = $m
AND t.`id` = $t
";
break;
#values are not empty, so the row is droped in the middle part
default:
#we set middle weigh exactly between top and bottom
$query = "
UPDATE `$table` m, `$table` t, `$table` b
SET m.`weight` = (t.`weight`+b.`weight`)/2
WHERE m.`id` = $m
AND t.`id` = $t
AND b.`id` = $b
";
break;
}
Yii::app()->db->createCommand($query)->query();
Even after 45 times of dividing 1 to 2, float value will not drop to zero, so I this solution is a remedy right now!
I have the following call to my database to retrieve the last row ID from an AUTO_INCREMENT column, which I use to find the next row ID:
$result = $mysqli->query("SELECT articleid FROM article WHERE articleid=(SELECT MAX(articleid) FROM article)");
$row = $result->fetch_assoc();
$last_article_id = $row["articleid"];
$last_article_id = $last_article_id + 1;
$result->close();
I then use $last_article_id as part of a filename system.
This is working perfectly....until I delete a row meaning the call retrieves an ID further down the order than the one I want.
A example would be:
ID
0
1
2
3
4-(deleted row)
5-(deleted row)
6-(next ID to be used for INSERT call)
I'd like the filename to be something like 6-0.jpg, however the filename ends up being 4-0.jpg as it targets ID 3 + 1 etc...etc...
Any thoughts on how I get the next MySQL row ID when any number of previous rows have been deleted??
You are making a significant error by trying to predict the next auto-increment value. You do not have a choice, if you want your system to scale... you have to either insert the row first, or rename the file later.
This is a classic oversight I see developers make -- you are coding this as if there would only ever be a single user on your site. It is extremely likely that at some point two articles will be created at almost the same time. Both queries will "predict" the same id, both will use the same filename, and one of the files will disappear, one of the table entries may point to the wrong file, and the other entry will reference a file that does not exist. And you'll be scratching your head asking "how did this happen?!"
Predicting auto-increment values is bad practice. Don't do it. Plan for concurrency.
Also, the information_schema tables are not really tables... they are server internals exposed to the SQL interface. Calls to the "tables" table, and show table status are expensive calls that you do not want to make in production... so don't be tempted to use something you find there.
You can use mysql_insert_id() after you insert the new row to retrieve the new key:
$mysqli->query($yourQueryHere);
$newId = $mysqli->insert_id();
That requires the id field to be a primary key, though (I believe).
As for the filename, you could store it in a variable, then do the query, then change the name and then write the file.
I'm trying to count a table row and add 1 on the outcome, I have this snippet of code.
$countQuery = "SELECT COUNT(id) FROM donations";
$outcomeQuery = mysql_query($countQuery);
$countUp = mysql_fetch_array($outcomeQuery);
$plusOne = 1;
$outcome = $countUp;
echo $outcome[0]
or die(mysql_error());
But this gives me the error:
Fatal error: Unsupported operand types
I need this so I always have a unique number that's not used by a previous donator.
You could use:
SELECT COUNT(id)+1 as IDCount FROM donations
as your query instead. This will save you any mucking about in PHP to do the math. The array you pull back will have the number that you want right off the bat.
Edit: The better alternative however is to use a column type that increments automatically. In MySQL, this is done with the syntax auto_increment in the create table syntax.
Using this, you never actually have to insert a value, but rather, you pass it a NULL as follows (assuming that ID is the field with Auto_increment on it:
insert into tableName (ID,Name) values (null, 'Fluffeh');
So you see you don't give it any values for the ID column - the database takes care of using the right number.
use simple php
$countQuery = mysql_query("SELECT id FROM donations");
$count=mysql_num_rows($countQuery);
$count+=1;
It's dangerous to rely on COUNT to give you a unique number. What happens if two processes execute this query, and then both try and commit: you suddenly have the same value twice.
It would be much safer to implement some kind of sequence function independent of your table contents. This link shows one possibility:
http://forums.mysql.com/read.php?61,143867,238482#msg-238482
This question is for a MySQL database. I suggest you use the AUTO INCREMENT field type.
As you are using PHP, if you need to know the id after inserting a record, use:
mysql_query("INSERT INTO mytable (1, 2, 3, 'blah')");
$id = mysql_insert_id();
See mysql_insert_id().
Using
4 random generated numbers to make 100% sure there are no duplicates
will not make 100% sure there are no duplicates. Don't re-invent the wheel. This is how the problem of ensuring unique incrementing identifiers are used has been solved, you don't need the embarrassment of a homebrew solution that doesn't always work.
I have a form that lets users create new records,
In the field that is the id that auto-increments i want the user to see the record number that this record is by somehow showing latest value+1 in the fields value.
I was thinking of something like:
<input type="text" value="<?php echo $myQuery['recordId'].length+1"/>
But that doesn't work.
Again, this is only to get the default value in the <input>
Instead of having to look up the last id, And this form is only used by one admin.
You can find the one plus the highest id by selecting it:
SELECT MAX(id)+1 FROM table
But like David said, you're not guaranteed this will be the id that is used, because 2 people could load the page at about the same time.
To get the last id relevant to that connection, use mysql_insert_id
In your case you'll have to insert an empty record in the db before you can guarantee that it will count. It will leave a lot of empty records if the users don't proceed, but you can do a cleanup every time the form is loaded by deleting records created more than one hour ago that don't have a title value or something like that.
if you absolutely need it to be an integer, you can always create a special table with only one auto_increment column, insert to it, get the last_insert_id() and use that. this is kind of mimicking the sequences in oracle. the ids that dont get used will go waste, but the other problems associated with multiuser scenarios will not occur. The following code copied from mysql documentation on information functions. Go there to read on the promises of this code.
CREATE TABLE sequence (id INT NOT NULL);
INSERT INTO sequence VALUES (0);
UPDATE sequence SET id=LAST_INSERT_ID(id+1);
SELECT LAST_INSERT_ID();
Now back to my own words. If it does not have to be an integer you can use guid. There is a uniqid function in php, and there is a uuid function in mysql. the theory says even if everyone keeps generating guids independently all the time, every guid will be unique.
So this is one way of doing it:
<?php
$query = "select uuid()";
$result = mysql_query($query);
$row = mysql_fetch_row($result);
$uuid = $row[0];
?>
<input type="text" value="<?php echo $uuid; ?>"/>
I'm using PHP and PHPMyAdmin to create a small profile site.
I'm giving members an ID number, based on which is the biggest number currently in the database, +1
I did 25 tests before I got the PHP script where I wanted it to be.
I then deleted those 25 entries using PHPMyAdmin.
But now, when my PHP code does this:
function getLatestID() {
$query = "SELECT max(member_id) FROM members";
$result = #mysql_query($query) or showError("unable to query database for user information");
if (!($record = mysql_fetch_array($result))) return null;
return $record[0];
}
I get the wrong number.
Test scenario: the database table holds 3 entries, with ID's 1, 2 and 3.
I start a debugging session and put a breakpoint on the return $record[0].
I check its contents and instead of 3, which is the biggest number, it's 28.
As in 25+3=28, the 25 entries that I allready deleted...
Does anybody know what's causing this and how I can fix it?
It's probably because you have auto_increment set and the query is returning the highest id. When you deleted the other records, you probably didn't reset the auto increment count.
If you're using auto_increment in MySQL then deleting records won't decrease the next value.
You can empty a table with TRUNCATE TABLE mytable - this will reset the value.
You can also change value that auto-increment thinks is the next value to allocate:
ALTER TABLE members AUTO_INCREMENT = 3;
Note that if you put in a value that is less than the current max value in the auto-increment column, it'll change the value to that MAX+1. To see what the current next value is set to, do this:
SHOW CREATE TABLE members;
At the end of the table definition, it'll show "AUTO_INCREMENT = 26" or whatever it's current value is.