tags:

views:

314

answers:

7

Hello

I'm uploading image file to storage server. Before uploading I should compose filename, which contains AUTOINCREMENT VALUE in it (for example, 12345_filename.jpg).

How could I get autoincrement value before inserting into DB?

I see only one solution

  1. insert empty row
  2. get it's autoincrement value
  3. delete this row
  4. insert row with real data using autoincrement value from p.1

Is there any other solutions?

Thank you

+1  A: 

There is no solution. You get the auto-increment value when you insert a new row, full stop. Inserting and deleting won't help, since the next auto-increment value will be one higher. Do to possibly multiple clients talking to the database at the same time, you can't predict the next value since it might be incremented between your guessing and your actual insert.

Find a different solution. Either insert a row and update it later, or generate an id for the filename that's independent of the auto-increment id.

deceze
+7  A: 

The autoincrement value is generated by the database itself, when the insertion is done ; which means you cannot get it before doing the actual insert query.

The solution you proposed is not the one that's often used -- which would be :

  • insert some half-empty data
  • get the autoincrement value that's been generated
  • do your calculations, using that autoincrement value
  • update the row to put the new / full data in place -- using the autoincrement generated earlier in the where clause of the update query, to identify which row is being updated.

Of course, as a security precaution, all these operations have to be made in a transaction (to ensure a "all or nothing" behavior)


As pseudo-code :

begin transaction
insert into your table (half empty values);
$id = get last autoincrement id
do calculations
update set data = full data where id = $id
commit transaction
Pascal MARTIN
I'd also not recommend using the ID of the database row in your image filename for security. Instead, using something like `uniqid()`.
Stephen Melrose
A: 

well, try this:

$query = "SHOW TABLE STATUS LIKE 'tablename'";
$result = mysql_query($query);
$row = mysql_fetch_assoc($result);
var_dump($row);

output:

array(18) {
[...]
["Auto_increment"]=> string(4) "3847"
[...]
}

This will be your next auto_increment ID.

Alex
Yeah, thanks for the downvote for no reason!
Alex
I'd guess the reason would be was has been mentioned here several times: knowing the current/next id is not guaranteed to get you this id when you actually do the insert.
deceze
Yes, but if you know that there will be no other insert query in the meantime you could use this without any problems. I've had that case in some of my projects where I could safely use this.
Alex
Agreed. If you have total control over the application and are completely sure no other insert queries will happen in the meantime this could be usable (but I think a situation like that is very rare).
Richard Knop
A: 

Use mysql_insert_id() to get the last ID and then + 1

fire
You can not guarantee a record will not be inserted between the time you get the ID and the time you insert the record. @Pascal MARTIN's solution if the best approach.
Stephen Melrose
Would only work if you can guarantee there will be no other INSERT query in the meantime which is very rare and usually you cannot guarantee that 100%;
Richard Knop
A: 

@Pascal Martin makes a good point. In cases like this, I personally like to add another ID column, containing a random, 16-digit ID (which will also be the "public" ID in web apps and on web sites for security reasons). This random ID you can set beforehand in your application, work with it, and then set when the record is actually created.

Pekka
A: 

I think you can do it in following way:

  • in first call (ajax preferably) retrieve the current max value of autoincrement column from db using MAX in query.
  • insert your record with (above value + 1)_filename.jpg
Prashant
I also do agree with Pascal MARTIN's solution if it is a critical scenario which needs a transaction.
Prashant
A: 

Use a separate table just as a counter, like a postgresql sequence, and don't use auto_increment in your main table(s).

ysth