views:

95

answers:

3

Hello, I'm new with PL/SQL and I need last inserted id in data table after insert statement.

Like on MS SQL SELECT IDENT_CURRENT(‘tablename’)

Thanks in advance! Goran

+2  A: 

There is no built-it autoincrement fields in Oracle, you create it using sequences:

CREATE TABLE some_tab(
      rec_id      INTEGER,
      some_data   VARCHAR2(300)
);

CREATE SEQUENCE some_tab_seq;

CREATE OR REPLACE TRIGGER trig_BI
   BEFORE INSERT
   ON some_tab
   FOR EACH ROW
BEGIN
   IF :NEW.rec_id IS NULL
   THEN
      :NEW.rec_id := some_tab_seq.NEXTVAL ;
   END IF;
END;

Then in PL/SQL you can fetch current value of the sequence by

your_var := some_tab_seq.CURRVAL

Also in older version of Oracle you can't directly read NEXTVAL / CURRVAL into var and have to do:

SELECT some_tab_seq.CURRVAL
  INTO your_var
  FROM DUAL;
Alexander Malakhov
CURRVAL only works if we have previously selected a NEXTVAL from the sequence in the session.
APC
typo: rec_id <> id_rec
ammoQ
You can also look at select sequence_name, last_number from user_sequences, but concurrency and caching (especially on RAC) make this inexact.
Gary
ALL_SEQUENCES.LAST_NUMBER: "Last sequence number written to disk. If a sequence uses caching, the number written to disk is the last number placed in the sequence cache. This number is likely to be greater than the last sequence number that was used." http://download.oracle.com/docs/cd/E11882_01/server.112/e10820/statviews_2062.htm#i1588488
Shannon Severance
@Gary, @Shannon: wouldn't it require extra grants for user ? Can't recall this now. @ammoQ: thanks! fixed.
Alexander Malakhov
@APC: +1, forgot about this, thanks. So, in new session my only option is USER_SEQUENCES ?
Alexander Malakhov
@Alexander Malakhov: I don't think all sequences would require extra grants, it's just going to include those sequences you have access to. DBA_SEQUENCES would require extra grants. And if the table is in the users schema, USER_SEQUENCES is available. I don't think using *_SEQUENCES is very meaningful. If you the sequence caches, what you read in LAST_NUMBER will often be a number that has not been handed out yet.If you don't use caching concurrency and performance take a hit, since every fetch of NEXTVAL requires the equivalent of an autonomous transaction, complete with a commit.
Shannon Severance
+6  A: 

You can use the RETURNING clause:

insert into mytable(x,y) values (1,2) returning id into v_id;

This works well when there is a trigger that fills an id column, so you don't need the "select seq.currval from dual" thing.

ammoQ
+1 because your answer IMHO answers what I understood the OP's question to be
carpenteri
A: 

Oracle does not implement identity columns. It uses Sequences which generate unique numbers which can be used as PK values in any table.

So the expression IDENT_CURRENT('my_table') is best translated into MySequence.CURRVAL of the sequence feeding the table's PK.

Typically, you'd retrieve the inserted PK value in MS SQL by:

INSERT INTO MyTable ...
SELECT @PK = SCOPE_IDENTITY()

In Oracle, use the INSERT RETURNING clause to achieve similar functionality

DECLARE PK ...;
INSERT INTO MyTable
RETURNING TableID INTO PK;
devio