用 select 插入,得到插入的值
insert with select, get inserted value
我正在使用特定查询来生成没有自动增量的 ID:
'insert into global_ids (`id`) select (((max(id)>>4)+1)<<4)+1 from global_ids'
CREATE TABLE `global_ids` (
`id` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
我在获取最后插入的行 ID 时遇到问题(因为我没有使用自动增量,cur.lastrowid 是 None)
在我的案例中,如何获取插入的行 ID 值的结果?
如果不关心竞争条件,可以用SELECT MAX(id) AS id FROM global_ids
.
得到table中最高的id
值
但是,您确实关心竞争条件。如果您的 python 程序的两个副本是 运行 会怎样?一个可以插入,然后另一个可以在第一个执行我建议的 select 之前执行插入。如果发生这种情况,select 将 return 一个错误的值。
你可以试试
START TRANSACTION;
SELECT (((max(id)>>4)+1)<<4)+1 INTO @id FROM global_ids WITH UPDATE;
INSERT INTO global_ids (id) VALUES (@id);
COMMIT;
SELECT @id AS id;
使用事务序列化您的 id
生成/检索操作。 (这在 MyISAM tables 中不起作用,因为它们会忽略事务。)
但是,在 MySQL 中避免竞争条件麻烦的最佳方法是实际使用自动递增功能。你可以试试这个。
CREATE TABLE global_ids (
id INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
)
然后依次发出这些查询:
INSERT INTO global_ids () VALUES ();
SELECT (((LAST_INSERT_ID()>>4)+1)<<4)+1 AS id;
这将使用自动递增功能生成转换后的 id
值,而不会 运行 竞争条件的风险。
我正在使用特定查询来生成没有自动增量的 ID:
'insert into global_ids (`id`) select (((max(id)>>4)+1)<<4)+1 from global_ids'
CREATE TABLE `global_ids` (
`id` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
我在获取最后插入的行 ID 时遇到问题(因为我没有使用自动增量,cur.lastrowid 是 None)
在我的案例中,如何获取插入的行 ID 值的结果?
如果不关心竞争条件,可以用SELECT MAX(id) AS id FROM global_ids
.
id
值
但是,您确实关心竞争条件。如果您的 python 程序的两个副本是 运行 会怎样?一个可以插入,然后另一个可以在第一个执行我建议的 select 之前执行插入。如果发生这种情况,select 将 return 一个错误的值。
你可以试试
START TRANSACTION;
SELECT (((max(id)>>4)+1)<<4)+1 INTO @id FROM global_ids WITH UPDATE;
INSERT INTO global_ids (id) VALUES (@id);
COMMIT;
SELECT @id AS id;
使用事务序列化您的 id
生成/检索操作。 (这在 MyISAM tables 中不起作用,因为它们会忽略事务。)
但是,在 MySQL 中避免竞争条件麻烦的最佳方法是实际使用自动递增功能。你可以试试这个。
CREATE TABLE global_ids (
id INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
)
然后依次发出这些查询:
INSERT INTO global_ids () VALUES ();
SELECT (((LAST_INSERT_ID()>>4)+1)<<4)+1 AS id;
这将使用自动递增功能生成转换后的 id
值,而不会 运行 竞争条件的风险。