42

I have inserted a row with some data in a table where a primary key is present. How would one "SELECT" the primary key of the row one just inserted?

I should have been more specific and mentioned that I'm currently using SQLite.

Kushan Randima
  • 2,174
  • 5
  • 31
  • 58
Samuel Moriarty
  • 958
  • 1
  • 8
  • 20

9 Answers9

68

For MS SQL Server:

SCOPE_IDENTITY() will return you the last generated identity value within your current scope:

SELECT SCOPE_IDENTITY() AS NewID
Michael Fredrickson
  • 36,839
  • 5
  • 92
  • 109
  • 27
    Works for SQL Server - **but only** if you have a primary key of type `INT IDENTITY` (or `BIGINT IDENTITY`) - any other type of PK (like a GUID or something else) is **not** supported by `SCOPE_IDENTITY()` – marc_s Dec 12 '11 at 19:01
  • 1
    True, good point... I'll +1 your answer cause you've got that situation covered. – Michael Fredrickson Dec 12 '11 at 19:02
  • @marc_s: or numeric(x,0) too: guess the type of SCOPE_IDENTITY()... http://msdn.microsoft.com/en-us/library/ms190315.aspx – gbn Dec 12 '11 at 19:12
  • 1
    Thanks a heap. Although I should have been more specific and mentioned that I'm currently using SQLite. Anyway, I googled up "SCOPE_IDENTITY in SQLite" and found my answer. Cheers. Marking this as answer. – Samuel Moriarty Dec 13 '11 at 18:26
  • It doesn't work with `INSERT INTO ...; SELECT SCOPE_IDENTITY() AS NewID`. And I also tried to separate the 2 queries, `SELECT SCOPE_IDENTITY()` finally got value, but always is `0`, sad. – Zhang Jun 12 '23 at 12:09
57

For SQL Server 2005 and up, and regardless of what type your primary key is, you could always use the OUTPUT clause to return the values inserted:

INSERT INTO dbo.YourTable(col1, col2, ...., colN)
OUTPUT Inserted.PrimaryKey
VALUES(val1, val2, ....., valN)
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • 3
    This is the way to go, as it works on any primary key. It requires executing as a scalar query instead of a non-query execute, but that's trivial. – ChokesMcGee Apr 30 '15 at 04:14
  • 1
    Good method, but you have to use OUTPUT ... INTO ... to output into an intermediate table if your table has triggers. – Ian Jul 10 '15 at 18:52
  • 3
    This works (thanks!) but note that `PrimaryKey` isn't a keyword (and will result in `Invalid column name 'PrimaryKey'.` if you try and use it. It should be replaced by your actual column name. – Taran Jun 12 '19 at 09:01
  • @Taran: of course - I just wrote `PrimaryKey` to illustrate that here, whatever column is defined as primary key needs to be used (since the OP didn't mention what column is his primary key) – marc_s Jun 12 '19 at 09:41
  • 5
    @marc_s Yep, just leaving a comment for any future copy and paste dunces like me :) – Taran Jun 12 '19 at 12:38
  • @Taran, you're genius! – Zhang Jun 12 '23 at 12:13
8

SQL Server:

You can use @@IDENTITY. After an insert statement, you can run:

select @@identity

This will give you the primary key of the record you just inserted. If you are planning to use it later, I suggest saving it:

set @MyIdentity = @@identity

If you are using this in a stored procedure and want to access it back in your application, make sure to have nocount off.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Farhan
  • 2,535
  • 4
  • 32
  • 54
  • 5
    If you have an `IDENTITY` column - I would recommend you use [`SCOPE_IDENTITY()` rather than `@@IDENTITY`](http://blog.sqlauthority.com/2007/03/25/sql-server-identity-vs-scope_identity-vs-ident_current-retrieve-last-inserted-identity-of-record) – marc_s Dec 12 '11 at 19:19
6

For MySQL, use LAST_INSERT_ID()

http://dev.mysql.com/doc/refman/5.0/en/getting-unique-id.html

You should also be able to start a transaction, insert the row, and select the row using some field that has a unique value that you just inserted, like a timestamp or guid. This should work in pretty much any RDBMS that supports transactions, as long as you have a good unique field to select the row with.

Dagg Nabbit
  • 75,346
  • 19
  • 113
  • 141
  • Will only work if you have an auto increment field. What if I have a custom id field? I would have run another query to get that value. Is there any way around that? – blackmambo Jan 04 '20 at 16:05
3

If you need to retrieve the new index in MS SQL when there are triggers on the table then you have to use a little workaround. A simple OUTPUT will not work. You have to do something like this (in VB.NET):

DECLARE @newKeyTbl TABLE (newKey INT);
INSERT INTO myDbName(myFieldName) OUTPUT INSERTED.myKeyName INTO @newKeyTbl VALUES('myValue'); " & _
SELECT newKey FROM @newKeyTbl;"

If using .NET, then the return value from this query can be directly cast to an integer (you have to call "ExecuteScalar" on the .NET SqlCommand to get the return).

Ian
  • 4,169
  • 3
  • 37
  • 62
2

For SQLite:

SELECT [Column_1],  [Column_2],...  [Column_n]
FROM [YourTable]
WHERE rowid = (SELECT last_insert_rowid())

whereas:

  • Column_1, Column_2,... Column_n: are the primary key of YourTable.

If you'd created YourTable with primary key replaced rowid (i.e. one column pk defined as INTEGER PRIMARY KEY) you just use:

SELECT last_insert_rowid()

Which is a common case.
Finally, this wont work for WITHOUT_ROWID tables.

Please Check:

https://www.sqlite.org/lang_corefunc.html#last_insert_rowid

Esau
  • 21
  • 3
  • This does not provide an answer to the question. Once you have sufficient [reputation](https://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](https://stackoverflow.com/help/privileges/comment); instead, [provide answers that don't require clarification from the asker](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). - [From Review](/review/low-quality-posts/21998779) – Fullstack Guy Jan 22 '19 at 16:22
  • @AmardeepBhowmick, it's not a correct answer (returns the `rowid`, not the primary key, as requested by the OP), but it _is_ an answer. I'm voting `Looks OK.` – Eric Brandt Jan 22 '19 at 17:59
0

For PostgreSQL,

INSERT INTO tablename (col1, col2, ...)
VALUES (val1, val2, ...)
RETURNING idcol;

The optional RETURNING clause causes INSERT to compute and return value(s) based on each row actually inserted (or updated, if an ON CONFLICT DO UPDATE clause was used). This is primarily useful for obtaining values that were supplied by defaults, such as a serial sequence number. However, any expression using the table's columns is allowed.

https://www.postgresql.org/docs/current/sql-insert.html

Brian Burns
  • 20,575
  • 8
  • 83
  • 77
0

For Postgresql:

SELECT CURRVAL(pg_get_serial_sequence('schema.table','id'))

Source: PostgreSQL function for last inserted ID

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
z-index
  • 409
  • 8
  • 14
  • 3
    PGSQL can do better, check out RETURNING. – BastetFurry Apr 02 '14 at 10:46
  • 1
    Per comment by BastetFurry, see the `RETURNING` clause of [`INSERT`](http://www.postgresql.org/docs/current/static/sql-insert.html) command. To quote the doc: `The optional RETURNING clause causes INSERT to compute and return value(s) based on each row actually inserted. This is primarily useful for obtaining values that were supplied by defaults, such as a serial sequence number.` – Basil Bourque May 22 '15 at 01:04
-4
select MAX(id_column) from table

That, in theory, should return you that last inserted id. If it's a busy database with many inserts going on it may not get the one you just did but another.

Anyhow, an alternative to other methods.

dynabaul
  • 151
  • 2