Get the primary id of inserted line in SQL
I have a table, with autoincremented id
CREATE TABLE users (
id SERIAL NOT NULL,
name VARCHAR(30) NOT NULL,
PRIMARY KEY (id)
)
SQLSQL
I can add a new item there with an explicit id
INSERT INTO users (id, name) VALUES (2, 'fred')
SQLSQL
And while my id is autoincremented, I can omit it
INSERT INTO users (name) VALUES ('ed')
SQLSQL
So, this time, I don't know the id, and I want to somehow get it.
I could do it with LAST_IDENTITY() function, but it just uses %RowID, and have no relation to the primary id
SELECT LAST_IDENTITY()
SQLSQL
Gives 2, instead of 3
Is there any way, to make LAST_IDENTITY() match to the primary id key, or I just forget about it and use something else?
Product version: IRIS 2022.1
Found this way with IDENTITY and ALLOWIDENTITYINSERT=1
CREATE TABLE users ( id identity NOT NULL, name VARCHAR(30) NOT NULL, PRIMARY KEY (id) ) WITH %CLASSPARAMETER ALLOWIDENTITYINSERT = 1; INSERT INTO users (id, name) VALUES (2, 'fred'); SELECT LAST_IDENTITY(); INSERT INTO users (name) VALUES ('ed'); SELECT LAST_IDENTITY();
Not sure if actually a good way to solve the issue
See also
SET OPTION PKEY_IS_IDKEY = true
With this enabled your sample works as you expect
https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls...
InterSystems DB-API Driver does not support it, yet, But yeah, this can solve it, and I like this way more.
Hmm, it's system-wide, and now I see, that it's the wrong way. I can't use this. Are there any possibilities to have such option just for a process?
I guess
select id from users where %ID=2
would give you 3
Right, but from that point of code, I have no idea what the primary key is, I may get the table name, and that's it. And I don't want to do any extra queries, to find it out. Even the to do query with LAST_IDENTITY() seems too much for performance reasons. It's a part of Python SQLAlchemy ORM Dialect in my development right now.
In the case of JDBC, there's also the
getGeneratedKeys()
method that you may find useful.We're looking into support for a
RETURNING
clause for theINSERT
command as a possible enhancement (Postgres' flavour of this nonstandard clause is very nice), but don't hold your breath as we have a long list of such candidate enhancements and a much shorter list of people who can work on the surprising amount of places in our codebase that would need to be updated to accommodate such a syntax extension.Great news about RETURNING, yeah, that will help a lot, especially for external adapters.
And thanks for the tip with getGeneratedKeys
Well, looks like the result of getGeneratedKeys() exactly the same as LAST_IDENTITY()
no big surprise.
if IDKEY <> PrimaryKey then PrimaryKey is just a UNIQUE Key on some property.
I expected it as on object side you have %OpenId() but no %OpenPrimary() or similar.
only Classmethod <uniqueProperty>KeyOpen(...)
💡 This question is considered a Key Question. More details here.