Использовать текущее значение auto_increment в качестве основы для другого поля в том же запросе INSERT - возможно ли это в MySQL? - PullRequest
2 голосов
/ 20 апреля 2009

В моей таблице (MySQL) у меня есть следующие поля:

id - первичный, auto_increment

hash - базовое представление 36 id

Я бы хотел заполнить оба поля одновременно, используя хранимую процедуру для вычисления базового 36 эквивалента значения id, полученного при INSERT. Примерно так:

INSERT into `urls` (`id`,`hash`) VALUES (NULL,base36(`id`));

Очевидно, это не работает, но я надеюсь, что это иллюстрирует то, чего я пытаюсь достичь. Возможно ли это, и если да, то как?

Примечание: я хочу использовать только один запрос, поэтому last_insert_id не поможет (по крайней мере, как я понимаю).

Ответы [ 3 ]

5 голосов
/ 20 апреля 2009

Этот вопрос по сути является повторением этого другого . Вкратце, преимущество поля автоинкремента состоит в том, что значение гарантировано уникально, а недостатком является то, что значение не существует до тех пор, пока INSERT уже не будет выполнен.

Это обязательно дело. Например, вы можете получить для данной таблицы значение следующего значения автоматического приращения, но из-за проблем с параллелизмом вы не можете быть уверены, что запрос , который вы выполните следующим, будет таким этот идентификатор. Кто-то другой может принять это первым. Следовательно, назначение поля ID должно быть атомарной операцией получения и приращения, которая происходит при вставке записи.

Другими словами, хотя вы можете хотеть сделать это в одном запросе, вы просто не собираетесь этого делать. Есть способ, которым вы теоретически можете притвориться, что выполняете только один запрос, добавив триггер INSERT, который добавляет ваше альтернативное представление поля ID после факта. Кроме того, вы можете использовать поле идентификатора без автоматического увеличения, основанное на чем-то заранее известном.

2 голосов
/ 20 апреля 2009

Хотя вы не можете сделать это в одном запросе, вы можете сделать это:

START TRANSACTION;
INSERT into `urls` (`id`) VALUES (NULL);
UPDATE `urls` SET `hash`=BASE36(`id`) WHERE `id`=LAST_INSERT_ID();
COMMIT;
0 голосов
/ 20 апреля 2009

Вы можете сделать это, используя триггер, что-то вроде:

CREATE TRIGGER `calc_id_hash` AFTER INSERT ON `urls`
FOR EACH ROW SET new.`hash`= BASE36(new.`id`);
...