插入 table 并将另一列设置为自动递增的列值

Insert into a table and set another column to autoincremented column value

假设我有一个简单的 table:

create table foo
{
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    bar INTEGER
}

我想插入一个新行,这样 id == bar 其中 id 的值由数据库选择,a.k.a。自动递增。

像这样:

INSERT INTO foo (id, bar) VALUES (NULL, id)

是否可以在一条语句中做到这一点?

SQL 语法是什么?

你不能two auto increment fields。您应该使用单个自动递增字段。鉴于这两个字段在每一行中始终具有相同的值,因此无论如何都没有理由必须使用这些字段。

但是你可以只创建触发器,它会在插入行后更新另一个等于自动增量值的字段。并在您不希望它们具有相同值时删除该触发器。

CREATE TRIGGER update_foo AFTER INSERT ON foo 
  BEGIN
    UPDATE foo SET bar = NEW.id ;
  END;

当最终 bar 将更改为具有与 id 不同的值时,然后删除触发器

DROP TRIGGER update_foo

INSERT INTO foo (bar) VALUES (id)

如评论中所述,我相信这将特定于每个数据库实现,因此了解您使用的是哪个服务器会很有用。但是,对于 MySQL,您可以这样做:

INSERT INTO foo (bar) 
  SELECT AUTO_INCREMENT 
  FROM information_schema.tables 
  WHERE table_schema = DATABASE() 
    AND TABLE_NAME = 'foo';

或者,由于您可能正在使用 SQLite(基于标签),您可以试试这个:

INSERT INTO foo (bar) 
  SELECT (seq + 1)
  FROM sqlite_sequence
  WHERE name = 'foo';

这不是在一个查询中完成的,但可以在存储过程中使用。重复该集合以表明它确实根据数据库创建的 ID 进行插入和更新。这是在 SQL Server 2008R2

上完成的
declare @tmpTable TABLE (
    id INT identity(1,1),
    bar INT
    )

    declare @myId INT
    insert @tmpTable (bar) values (0)
    SET @myId = SCOPE_IDENTITY() 
    update @tmpTable SET bar = @myId where id = @myId 

    insert @tmpTable (bar) values (0)
    SET @myId = SCOPE_IDENTITY() 
    update @tmpTable SET bar = @myId where id = @myId 


    insert @tmpTable (bar) values (0)
    SET @myId = SCOPE_IDENTITY() 
    update @tmpTable SET bar = @myId where id = @myId 


    insert @tmpTable (bar) values (0)
    SET @myId = SCOPE_IDENTITY() 
    update @tmpTable SET bar = @myId where id = @myId 

    select * FROM @tmpTable 

输出

id  bar
1   1
2   2
3   3
4   4

在 SQLite 中你可以

BEGIN TRANSACTION;
  INSERT INTO foo (id, bar) VALUES (NULL, 0);
  UPDATE foo SET bar = id WHERE _ROWID_ = last_insert_rowid();
COMMIT;

确保没有其他语句妨碍您的双语句表达式。

您可以将其用作:

INSERT INTO foo (bar) VALUES (last_insert_rowid()+1)

The ID that was generated is maintained in the server on a per-connection basis. This means that the value returned by the function to a given client is the first AUTO_INCREMENT value generated for most recent statement affecting an AUTO_INCREMENT column by that client. This value cannot be affected by other clients, even if they generate AUTO_INCREMENT values of their own. This behavior ensures that each client can retrieve its own ID without concern for the activity of other clients, and without the need for locks or transactions.

insert into [Test].[dbo].[foo] (bar) select MAX(id)+1 from [Test].[dbo].[foo]