Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting id after insert within a transaction (Oracle)

Let's say I have three tables: team, player, team_player. Table team_player is a bridge table allowing a "many to many" relationship.

When someone wants to create a new team, they specify the initial players on that team.

How do I insert both the team and team_player rows in the same transaction? That is, I'd like to insert all the team_player records before committing to the new team row. I am using JDBC and Oracle.

When I try the code below, teamId is filled with a string of letters even though team.id is a number (that is incremented by a trigger). So, this does not seem to be the id of the record which I just tried to insert (but didnt commit to yet).

c = DB.getConnection();
c.setAutoCommit(false);

sql = "INSERT INTO team (name) values (?)";
myInsert = c.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
myInsert.setString(1, "cougars");
int affectedRows = memoInsert.executeUpdate();

String teamId;
ResultSet generatedKeys = myInsert.getGeneratedKeys();
if (generatedKeys.next()) {
    teamId = generatedKeys.getString(1);
}

// ...loop through players inserting each player and team.id into team_player

// c.commit();

This is where I read about RETURN_GENERATED_KEYS: How to get the insert ID in JDBC?

like image 411
latj Avatar asked Jul 03 '13 22:07

latj


People also ask

How to return id after insert Oracle?

SQL> create table t(id number, text varchar2(20)) 2 / Table created. SQL> create sequence tSeq 2 / Sequence created. SQL> create trigger tT before insert on t for each row 2 begin 3 :new.id := tSeq. nextval; 4 end; 5 / Trigger created.

Can we use case in insert statement in Oracle?

In the insert statement, you can we are using a Case statement to define corresponding value to insert in the employee table. In the Case statement, it checks for the required values and inserts values from THEN expression in the table.

What is the purpose of Oracle insert into statement?

The INSERT statement adds one or more new rows of data to a database table. For a full description of the INSERT statement, see Oracle Database SQL Reference. Another (usually short) name for the referenced table or view. A list of columns in a database table or view.

How do I insert into Oracle?

To insert data into Oracle tables using SQL-Plus, you must be logged on to the server. Data can be added to tables via the INSERT statement. Remember that this inserts data one row at a time. You can create your INSERT statements in notepad or other similar editor, and copy them into the SQL-Plus editor.

How to retrieve the last inserted identity in Oracle 12c?

Since Oracle 12c we can use IDENTITY fields. Is there a way to retrieve the last inserted identity (i.e. select @@identity or select LAST_INSERTED_ID () and so on)? The identity columns still use a sequence in the background. You should be able to use the usual sequence.currval to obtain the last generated value.

What is a transaction ID in SQL?

A transaction ID is unique to a transaction and represents the undo segment number, slot, and sequence number. The following example execute an UPDATE statement to begin a transaction and queries V$TRANSACTION for details about the transaction: SQL> UPDATE hr.employees SET salary=salary; 107 rows updated.

How to get ID generated from sequence on INSERT statement?

It is possible to get ID generated from SEQUENCE on insert statement using RETURNING clause.

Why did Oracle implement identity?

It seems that Oracle implemented IDENTITY just to say that they support identities. Everything is still implemented using SEQUENCES and sometimes you need to access the SEQUENCE to make some of the work (i.e. retrieve the latest inserted IDENTITY ).


1 Answers

The Oracle JDBC Driver does not support getGeneratedKeys() - you are manually generating the keys in your trigger, presumably from a SEQUENCE.

You can use Oracle's returning clause:

String query = "BEGIN INSERT INTO team (name) values (?) returning id into ?; END;";
CallableStatement cs = conn.prepareCall(query);
cs.setString(1, "cougars");
cs.registerOutParameter(2, OracleTypes.NUMBER);
cs.execute();
System.out.println(cs.getInt(2));

Or grab the last sequence number with a second SQL query:

SELECT mysequence.CURRVAL FROM dual
like image 139
samlewis Avatar answered Nov 09 '22 01:11

samlewis