views:

51

answers:

2

I have table with auto increment primary key. I want insert a bunch of data into it and get keys for each of them without additional queries.

START TRANSACTION;
INSERT INTO table (value) VALUES (x),(y),(z);
SELECT LAST_INSERT_ID() AS last_id;
COMMIT;

Could MySQL guarantee, that all data would be inserted in one continuous ordered flow, so I can easily compute id's for each element?

id(z) = last_id;
id(y) = last_id - 1;
id(x) = last_id - 2;
A: 

As far as i know, this will work in pretty much all SQL-engines out there.

elusive
Just to be sure, is there any proofs? Official docs or something.
Andrew
Since only the highest ID is stored as `AUTOINCREMENT`-value for each table, its unlikely that some SQL-engine will use released IDs again.
elusive
In situation of concurrent inserts? And what about order, is it always the same as in query?
Andrew
Since it's in a transaction, you can't have concurrent inserts. As for order, I'm unsure.
Mike M.
@Elsuive: In fact, if you begin a transaction, insert, then rollback, the ID's generated used during the life of the transaction will be 'lost' and not recycled. At least in every RDBMS I have ever used. [I also belive the OP is looking for definitive answers, not 'unlikely'.]
Dems
+1  A: 

If you begin a transaction and then insert data into a table, that whole table will become locked to that transaction (unless you start playing with transaction isolation levels and/or locking hints).

That is bascially the point of transactions. To prevent external operations altering (in anyway) that which you are operating on.

This kind of "Table Lock" is the default behaviour in most cases.

In unusual circumstances you can find the the RDBMS has had certain options set that mean the 'normal' default (Table Locking) behaviour is not what happens for that particular install. If this is the case, you should be able to override the default by specifying that you want a Table Lock as part of the INSERT statement.

EDIT:

I have a lot of experience on MS-SQL Server and patchy experience on many other RDBMSs. In none of that time have I found any guarantee that an insert will occur in a specific order.

One reason for this is that the SELECT portion of the INSERT may be computed in parallel. That would mean the data to be inserted is ready out-of-order.

Equally where particularly large volumes of data are being inserted, the RDBMS may identify that the new data will span several pages of memory or disk space. Again, this may lead to parallelised operation.

As far as I am aware, MySQL has a row_number() type of function, that you could specify in the SELECT query, the result of which you can store in the database. You would then be able to rely upon That field (constructed by you) but not the auto-increment id field (constructed by the RDBMS).

Dems