Sql 获取最后一个插入id的标准方法是什么?

Sql 获取最后一个插入id的标准方法是什么?,sql,mysql,sql-server,postgresql,standards,Sql,Mysql,Sql Server,Postgresql,Standards,获取最后一个插入id的sql标准是什么?如果有这样的事 mysql:最后一个\u插入\u ID postgresql:。。。返回f_id mssql:范围_标识 ... 这里有更多的例子 我的意思是,所有数据库对此都有不同的实现,对于这样一个常见的任务没有一个标准?Oracle和PostgreSQL支持RETURNING子句,并使用一个名为sequence的对象来提供自动顺序编号。SQL Server的下一个版本denali设置为支持序列,但我还没有看到word是否支持RETURNING子句。获

获取最后一个插入id的sql标准是什么?如果有这样的事

mysql:最后一个\u插入\u ID postgresql:。。。返回f_id mssql:范围_标识 ... 这里有更多的例子


我的意思是,所有数据库对此都有不同的实现,对于这样一个常见的任务没有一个标准?

Oracle和PostgreSQL支持RETURNING子句,并使用一个名为sequence的对象来提供自动顺序编号。SQL Server的下一个版本denali设置为支持序列,但我还没有看到word是否支持RETURNING子句。获取当前序列值的另一种方法是:

Oracle: sequence_name.CURRVAL 
PostgreSQL: CURRVAL('sequence_name')
DB2支持和子句

选择最大自动增量列。。。这不是推荐的做法,因为它不可靠。在Oracle中,写入程序插入/更新不会阻止读卡器选择,因此无法保证值正确

结论 我不知道,包括使用序列进行自动编号,但目前还没有实现检索值的一致方法。

请参见此答案

简而言之,除了MAXID之外,没有跨数据库的方法可以做到这一点,但这并不是一个保证的结果,并且有许多缺陷,例如

其他插入可以位于最后一次插入和最大查询之间 无法与高事务表一起使用max将发出读取锁定,rdbms特定方法不会从任何表读取 与标识/自动编号/自动增量/序列相关的ANSI标准首次出现在所有主要RDBMS的等待实现中。它很可能类似于Oracle/PostgreSQL序列

SQL:2003标准对SQL:1999(也称为SQL3)的所有部分进行了细微的修改,并正式引入了一些新功能,例如:-序列生成器,它允许标准化序列

SQL:2003中的另一个变化是OUTPUTUSING子句,但是关于它的信息很少。Sybase和SQL Server用它做了不同的事情,因此目前还不清楚它将如何实现。SQLServer将其实现为

INSERT INTO TBL(..)
OUTPUT inserted.identity_col
INTO @sometablevar
VALUES(..)

这与其说是一个真正的新答案,不如说是对一些评论的澄清,但它更适合这里。只要客户端处于可序列化事务中,select maxid就可以正常工作。在pgsql中,您可以向自己证明这一点。打开两个psql会话,然后运行此会话,首先在默认的read committed中运行,然后在serializable中运行:

p1: create table test (id serial);
p1 and p2: begin;
p1 and p2: set transaction isolation level serializable;
p1: insert into test values (DEFAULT);
p2: insert into test values (DEFAULT);
p1: select max(id) from test;
 1
p2: select max(id) from test;
 2
p2: commit;
p1: select max(id) from test;
 2
但是,在read提交的情况下:

p1: create table test (id serial);
p1 and p2: begin;
p1 and p2: set transaction isolation level read committed;
p1: insert into test values (DEFAULT);
p2: insert into test values (DEFAULT);
p1: select max(id) from test;
 1
p2: select max(id) from test;
 2
p2: commit;
p1: select max(id) from test;
 1
性能方面的可序列化事务可能会产生负面影响,或导致事务失败,必须回滚并重试,等等


返回或返回是更好的主意。但是,如果执行maxid的事务是可序列化的,那么说maxid不能被信任是错误的。

一种技术可能适用于所有数据库,并且在序列不是简单的递增数字的情况下,例如,存在具有高id的预存行,因此您不能使用MAX,即:

确定下一个id是什么,例如使用nextval功能或类似功能。 使用该id插入行。 使用该id满足您的其他需求。
我有一个。。如果ID列为int并自动递增。最后一行是b maxID。。这就是你的意思吗?@william天真,但有道理:P@william:在抓取MAXid之前发生另一次插入时会发生什么情况?@mu:我想插入的行将被检索。。插入到表值中。。。然后从id=maxid.的表中选择*。。插入的行u将被检索。这是我的假设,MAXid错了。选择最后插入值的ID的标准方法是使用一个包含所有插入值的条件查询。因此,如果您确实在表a、b、c中插入值a、b、c,您将使用SELECT ID FRM table返回ID,其中a=a、b=b和c=c。如果存在重复值,当然不能依赖于此,例如记录a、b、c不是唯一的。我不确定SQL Server是否支持nextval或类似的功能,但我们可以暂时假装它只是服务器产品的一个小品种,所以它不算数。我想知道的是你的方法实际上应该如何工作。下面是一个场景:插入一行,然后很快删除。此后没有插入更多行,但即将添加一行。此时的MAXID是一些N。新行将以ID=N+2插入,因为N+1是最近插入和删除的行的ID。使用nextval是否可以正确解决这种情况?您的意思是只要每个客户端都在可序列化事务中?唯一需要在可序列化事务中的客户端就是执行maxid的客户端。其他做其他事情的客户机可以处于任何一种模式。