Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Figure out how to return last inserted ID from Oracle DB using reactive-oracle-client #566

Closed
jsmrcka opened this issue Mar 11, 2022 · 4 comments
Assignees
Labels
help wanted Extra attention is needed

Comments

@jsmrcka
Copy link
Contributor

jsmrcka commented Mar 11, 2022

Problem encountered in https://github.com/jsmrcka/quarkus-test-suite/blob/d93d2700b93b5607df1846af2ea6adc97369cdd7/sql-db/vertx-sql/src/main/java/io/quarkus/qe/vertx/sql/services/DbPoolService.java#L96, while trying to implement Oracle-specific save method.

Sample of DDL:

CREATE TABLE airports (
  id            NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
  iata_code     VARCHAR(100) NOT NULL UNIQUE,
  city          VARCHAR(100) NOT NULL
);

Tried out approach: look for a sequence, which should be automacially generated upon creation of the IDENTITY column, and invoke CURRVAL.
(Inspired by https://www.oracletutorial.com/oracle-sequence/oracle-create-sequence/.)

    protected Uni<Long> saveOracle(String tableName, List<String> fieldsNames, List<Object> fieldsValues) {
        return SqlClientHelper.inTransactionUni(this, tx -> {
            String fields = tableFieldsToString(fieldsNames);
            String values = tableFieldsValuesToString(fieldsValues);

            tx.preparedQuery("INSERT INTO " + getTableName(tableName) + " (" + fields + ") VALUES (" + values + ")").execute();
            return tx.query(
                    "SELECT b.name AS sequence_name FROM sys.idnseq$ c JOIN obj$ a ON c.obj# = a.obj# JOIN obj$ b ON c.seqobj# = b.obj# WHERE a.name = '"
                            + getTableName(tableName) + "'")
                    .execute()
                    .onItem().transform(rows -> rows.iterator().next().getString("sequence_name"))
                    .chain(seqName -> tx.query("SELECT " + seqName + ".CURRVAL l_id FROM DUAL")
                            .execute()
                            .onItem().transform(rows -> rows.iterator().next().getLong("l_id")));
        });
    }

However, this does not work:

io.vertx.core.VertxException: Error : 942, Position : 59, Sql = SELECT b.name AS sequence_name FROM sys.idnseq$ c JOIN sys.obj$ a ON c.obj# = a.obj# JOIN sys.obj$ b ON c.seqobj# = b.obj# WHERE a.name = 'address', OriginalSql = SELECT b.name AS sequence_name FROM sys.idnseq$ c JOIN sys.obj$ a ON c.obj# = a.obj# JOIN sys.obj$ b ON c.seqobj# = b.obj# WHERE a.name = 'address', Error Msg = ORA-00942: table or view does not exist

I tried to adopt other approaches used for other DBs in https://github.com/jsmrcka/quarkus-test-suite/blob/QUARKUS-1407-vertx-sql/sql-db/vertx-sql/src/main/java/io/quarkus/qe/vertx/sql/services/DbPoolService.java, but with no luck - AFAIK, Oracle does not provide anything similar to

INSERT INTO .. RETURNING id

or

SELECT LAST_INSERT_ID()

Any help appreciated.

@jsmrcka
Copy link
Contributor Author

jsmrcka commented Mar 23, 2022

@Sanne

@jsmrcka
Copy link
Contributor Author

jsmrcka commented Mar 23, 2022

@tsegismont

@tsegismont
Copy link

@jsmrcka
Copy link
Contributor Author

jsmrcka commented Mar 23, 2022

@tsegismont That did the trick. Thanks an awful lot!
I don't know how I was able to not notice such an obvious and well documented solution, but I did.

@jsmrcka jsmrcka closed this as completed Mar 23, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants