SQL:如何获取我刚刚插入的值的ID?

时间:2020-03-05 18:48:10  来源:igfitidea点击:

我在表中插入了一些值。有一个其值是自动生成的列。在我的代码的下一个语句中,我想检索此值。

你能告诉我如何正确地做吗?

解决方案

回答

SELECT @@Scope_Identity as Id

还有@@ identity,但是如果我们有触发器,它将返回在触发器期间发生的事情的结果,其中scope_identity尊重范围。

回答

请记住,@@ IDENTITY返回当前连接的最新创建的标识,而不必返回表中最近添加的行的标识。我们应该始终使用SCOPE_IDENTITY()返回最近添加的行的标识。

回答

我们正在使用什么数据库?据我所知,没有数据库不可知的方法来执行此操作。

回答

这就是我使用自动生成的ID进行MSSQL存储过程的方式。

CREATE PROCEDURE [dbo].[InsertProducts]
    @id             INT             = NULL OUT,
    @name           VARCHAR(150)    = NULL,
    @desc           VARCHAR(250)    = NULL

AS

    INSERT INTO dbo.Products
       (Name,
        Description)
    VALUES
       (@name,
        @desc)

    SET @id = SCOPE_IDENTITY();

回答

如果我们使用PHP和MySQL,则可以使用mysql_insert_id()函数,该函数将告诉我们刚刚插入的项目的ID。
但是如果没有语言和DBMS,我只是在黑暗中拍摄。

回答

@@ IDENTITY是不安全的,如果原始表上有插入触发器,则会从另一个表中获取ID,请始终使用SCOPE_IDENTITY()

回答

Rob的答案将是与供应商无关的,但是如果我们使用MySQL,则更内置的LAST_INSERT_ID()函数将是更安全正确的选择。

回答

同样,没有语言不可知的响应,但是在Java中,它是这样的:

Connection conn = Database.getCurrent().getConnection();  
PreparedStatement ps =  conn.prepareStatement(insertSql, Statement.RETURN_GENERATED_KEYS);
try {  
    ps.executeUpdate();  
    ResultSet rs = ps.getGeneratedKeys();  
    rs.next();  
    long primaryKey = rs.getLong(1);  
} finally {  
    ps.close();  
}

回答

如果我们正在使用Oracle,请执行以下操作:

Inset into Table (Fields....) values (Values...) RETURNING (List of Fields...) INTO (variables...)

例子:

INSERT INTO PERSON (NAME) VALUES ('Hyman') RETURNING ID_PERSON INTO vIdPerson

或者,如果我们是从...使用CallableStatement进行Java调用(很抱歉,这是我的领域)

INSERT INTO PERSON (NAME) VALUES ('Hyman') RETURNING ID_PERSON INTO ?

并声明该语句的自变量参数

回答

重要说明是,使用供应商SQL查询来检索最后插入的ID是安全的,而不必担心并发连接。

我一直认为我们必须创建一个事务才能插入一行,然后选择最后插入的ID,以避免检索另一个客户端插入的ID。

但是这些特定于供应商的查询始终会检索到当前与数据库的连接的最后插入的ID。这意味着最后插入的ID不会受到其他客户端插入的影响,只要它们使用自己的数据库连接即可。

回答

没有标准的方法可以做到(就像没有自动创建ID的标准方法一样)。这是在PostgreSQL中执行此操作的两种方法。假设这是表:

CREATE TABLE mytable (
  id SERIAL PRIMARY KEY,
  lastname VARCHAR NOT NULL,
  firstname VARCHAR
);

只要它们是同一连接中的连续语句,就可以在两个语句中执行此操作(在具有连接池的PHP中这是安全的,因为在脚本完成之前PHP不会将连接返回给池):

INSERT INTO mytable (lastname, firstname) VALUES ('Washington', 'George');
SELECT lastval();

lastval()为我们提供当前连接中使用的最后一个自动生成的序列值。

另一种方法是在INSERT语句上使用PostgreSQL的RETURNING子句:

INSERT INTO mytable (lastname) VALUES ('Cher') RETURNING id;

这种形式就像SELECT语句一样返回结果集,并且对于返回任何一种计算出的默认值也很方便。

回答

对于SQL 2005:

假设下表定义:

CREATE TABLE [dbo].[Test](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [somevalue] [nchar](10) NULL,
)

我们可以使用以下内容:

INSERT INTO Test(somevalue)
OUTPUT INSERTED.ID
VALUES('asdfasdf')

它将返回ID列的值。

回答

这就是我使用参数化命令完成的方式。

微软SQL

INSERT INTO MyTable (Field1, Field2) VALUES (@Value1, @Value2); 
 SELECT SCOPE_IDENTITY();

的MySQL

INSERT INTO MyTable (Field1, Field2) VALUES (?Value1, ?Value2);
 SELECT LAST_INSERT_ID();

回答

  • 插入具有已知GUID的行。
  • 使用此向导获取autoId字段。

这适用于任何类型的数据库。

回答

基于环境的Oracle解决方案:

CREATE OR REPLACE PACKAGE LAST
AS
ID NUMBER;
FUNCTION IDENT RETURN NUMBER;
END;
/

CREATE OR REPLACE PACKAGE BODY LAST
AS
FUNCTION IDENT RETURN NUMBER IS
    BEGIN
    RETURN ID;
    END;
END;
/

CREATE TABLE Test (
       TestID            INTEGER ,
    Field1      int,
    Field2      int
)

CREATE SEQUENCE Test_seq
/
CREATE OR REPLACE TRIGGER Test_itrig
BEFORE INSERT ON Test
FOR EACH ROW
DECLARE
seq_val number;
BEGIN
IF :new.TestID IS NULL THEN
    SELECT Test_seq.nextval INTO seq_val FROM DUAL;
    :new.TestID := seq_val;
    Last.ID := seq_val;
END IF;
END;
/

To get next identity value:
SELECT LAST.IDENT FROM DUAL

回答

这在SQL 2005中非常有效:

DECLARE @inserted_ids TABLE ([id] INT);

INSERT INTO [dbo].[some_table] ([col1],[col2],[col3],[col4],[col5],[col6])
OUTPUT INSERTED.[id] INTO @inserted_ids
VALUES (@col1,@col2,@col3,@col4,@col5,@col6)

如果INSERT语句插入多行,则具有返回所有ID的好处。

回答

sql = "INSERT INTO MyTable (Name) VALUES (@Name);" +
      "SELECT CAST(scope_identity() AS int)";
SqlCommand cmd = new SqlCommand(sql, conn);
int newId = (int)cmd.ExecuteScalar();

回答

从该网站我发现了以下内容:

SQL SERVER @@ IDENTITY与SCOPE_IDENTITY()与IDENT_CURRENT检索记录的最后插入的标识
2007年3月25日by pinaldave

选择@@ IDENTITY
它返回在连接上产生的最后一个IDENTITY值,而不管产生该值的表如何,也不管产生该值的语句的范围如何。
@@ IDENTITY将返回当前会话中输入到表中的最后一个身份值。虽然@@ IDENTITY仅限于当前会话,但不限于当前范围。如果我们在一个表上有一个触发器,导致要在另一个表中创建一个标识,则即使该触发器是创建它的触发器,我们也会获得最后创建的标识。

SELECT SCOPE_IDENTITY()
无论产生该表的表是什么,它都会返回在连接上和同一范围内的语句所产生的最后一个IDENTITY值。
像@@ IDENTITY一样,SCOPE_IDENTITY()将返回在当前会话中创建的最后一个标识值,但也会将其限制为当前范围。换句话说,它将返回我们显式创建的最后一个标识值,而不是由触发器或者用户定义的函数创建的任何标识。

SELECT IDENT_CURRENT(表名)
它返回在表中产生的最后一个IDENTITY值,而不管创建该值的连接如何,也不管产生该值的语句的范围如何。
IDENT_CURRENT不受范围和会话的限制;它仅限于指定的表。 IDENT_CURRENT返回在任何会话和任何作用域中为特定表生成的标识值。