插入 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]
假设我有一个简单的 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]