获取插入数据库表时记录得到的唯一 id

Posted

技术标签:

【中文标题】获取插入数据库表时记录得到的唯一 id【英文标题】:Get the unique id the record got when inserting to a database table 【发布时间】:2015-05-14 12:24:01 【问题描述】:

我有一个带有唯一 id 列的 oracle 表。当我向表中插入数据时,我会增加最后一个 id

insert into my_table vlaues((select max(id) from my_table), 'etc', 'etc');

可以有多个进程同时写入这个表。

自动提交是on

除了id之外,该表没有任何其他唯一列。

当我在表中插入一条记录时,有没有办法在我插入记录后获取记录得到的id 值?

如我所见,如果我在插入后使用 select max(id) from my_table,我可能无法获得插入语句中使用的 id,因为其他人可能在我发出 select 之前插入了另一条记录。

【问题讨论】:

这不是拥有自动递增 ID 的安全方法 - 同时访问会导致重复 ID(可能导致唯一键违规)。 Autoincrement in oracle to already created table 的可能重复项 还可以查看IDENTITY column autoincrement functionality in Oracle 12c 和Auto-increment primary key in Pre 12c releases 这个问题不仅仅是关于自动递增。插入 reord 后,我需要获取自动递增的值 如果你使用 PL/SQL 插入,那么你可以使用 返回子句 见***.com/questions/28472118/… 【参考方案1】:

Oracle 12 终于有了内置的标识列。因此,如果您使用的是最新版本的 Oracle,则可以使用它。阅读它here。

在早期版本中,最好使用序列。这保证了唯一性,即使在多线程环境中也是如此。我总是实现触发器来更新 id 列。 Here 是对类似问题的回答,它解释了如何执行此操作。

【讨论】:

我使用序列读取了您的解决方案,但不清楚插入记录时如何获取用于id 列的值。有什么想法吗? @LahiruChandima 你为什么不使用触发器? @Moudiz 我不熟悉触发器。如果它们可以用于此,我将研究触发器。 @LahiruChandima 您可以看到我的回答,了解如何使用 RETURNING 子句获取值。【参考方案2】:

你可以试试这个:

CREATE TABLE myTable( ID RAW(16) DEFAULT SYS_GUID())

另外,最好使用Sequence 来获取自动递增的 id。

如果你想在插入后获取序列id,你可以这样尝试:

declare
x  number;
id number;
begin
x := your_sequence.nextval;
insert into mytable (column1, column2, column3) 
values (x, value2, value3) returning x into id;

dbms_output.put_line(to_char(id));
end;

【讨论】:

@Lahiru Chandima:- returning 语法有什么问题?【参考方案3】:

最好在这种情况下使用序列(尽管您最终可能会出现数字间隙)。您可以使用 seq_abc1.currval/nextval 获取它们的当前/下一个值。

【讨论】:

间隙是必须的,通常它们没有错。如果没有间隙,一个事务将不得不等到其他提交(回滚),因此整个系统无法很好地扩展。 没错,我应该说“将”而不是“可能”【参考方案4】:

当我向表中插入一条记录时,有没有办法在我插入记录后获取记录得到的 id 值?

只需使用 RETURNING 子句。

例如-

RETURNING identity_id INTO variable_id;

测试用例 -

SQL> set serveroutput on
SQL> CREATE TABLE t
  2    (ID NUMBER GENERATED ALWAYS AS IDENTITY, text VARCHAR2(50)
  3    );

Table created.

SQL>
SQL> DECLARE
  2    var_id NUMBER;
  3  BEGIN
  4    INSERT INTO t
  5      (text
  6      ) VALUES
  7      ('test'
  8      ) RETURNING ID INTO var_id;
  9    DBMS_OUTPUT.PUT_LINE('ID returned is = '||var_id);
 10  END;
 11  /
ID returned is = 1

PL/SQL procedure successfully completed.

SQL>

SQL> select * from t;

        ID TEXT
---------- --------------------------------------------
         1 test

SQL>

您也可以对 pre-12c 版本使用相同的 RETURNING 技术,但您没有 IDENTITY 列。 returning 子句将返回您插入到表中的值。

【讨论】:

以上是关于获取插入数据库表时记录得到的唯一 id的主要内容,如果未能解决你的问题,请参考以下文章

Oracle怎么得到刚刚新插入数据库那条记录的id

将不存在的记录插入Mysql表

我似乎无法从 MySQL 获取最后插入的记录/ID

将希伯来语字符插入 MySQL 表时获取问号

使用 JPA 获取最后插入记录的主键

使用 FORALL 和 RETURNING 插入表时如何获取 ROWID