вставить с помощью выбора, получить вставленное значение - PullRequest
0 голосов
/ 30 мая 2018

Я использую специальный запрос для генерации идентификаторов без автоинкремента:

'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;

У меня проблема с извлечением идентификатора последней вставленной строки (поскольку я не использую автоинкремент, cur.lastrowid отсутствует)

Как мне получить результат вставленного значения идентификатора строки в моем случае?

1 Ответ

0 голосов
/ 30 мая 2018

Если вас не волнуют условия гонки, вы можете получить самое высокое значение id в таблице с помощью SELECT MAX(id) AS id FROM global_ids.

Но вам действительно важны условия гонки.Что произойдет, если запущены две копии вашей программы на Python?Один может сделать вставку, затем другой может сделать вставку, прежде чем первый сделает выбор, который я предложил.Если это произойдет, выбор вернет неправильное значение.

Вы можете попробовать

     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, потому что они игнорируют транзакции.)

Но лучше всего избегать неприятностей с состоянием гонки в 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 без выполненияриск условий гонки.

...