сложная вставка - PullRequest
       18

сложная вставка

0 голосов
/ 12 мая 2011

Я использую mysql / php.

моя таблица выглядит как

id (int autoincrement)  
voucher(varchar 25)

Я генерирую коды ваучеров, где код:

  • 1 случайныйчисло (например, 64)
  • 1 фиксированное число (например, 352)
  • значение поля id (1,2,3,4,5 ...)
  • 1 checkdigit(алгоритм Луна).

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

Вместо этого я хочу

сделать insert into vouchers (voucher) value('64352') и заставить его генерировать меня.

Как я могу это сделать?функция / триггер?

Ответы [ 2 ]

1 голос
/ 12 мая 2011

Если вы используете InnoDB, проще всего будет использовать существующий код и заключить его в транзакцию MySQL. то есть в псевдокоде:

mysql_query("START TRANSACTION");

# get next autoincrement value into: $next

# do your INSERT query

# get the actual last inserted ID into: $actual

if ($next === $actual) {
  mysql_query("COMMIT");
} else {
  mysql_query("ROLLBACK");
  # and raise an Exception or return an error
}

EDIT / ADD:

Поскольку вы упомянули триггеры, я изучил это и считаю, что это выполнимо. Пара вопросов.

  1. Доступ к "следующему автоинкрементному идентификатору" из триггера ... Я не знаю "хорошего" способа сделать это. В запросах INSERT у вас есть доступ только к НОВЫМ, а не к СТАРЫМ (существующим строкам) значениям (см. Синтаксис триггера ). В этом примере я просто поддерживаю отдельный счетчик @vcount на сервере. Чтобы инициализировать это значение тем идентификатором, который вы используете в данный момент, вы просто должны сделать «SET @vcount = 42;»

  2. Алгоритм Луна. Вы должны будете реализовать это как функцию SQL. Вот валидатор Luhn в SQL, с которого вы могли бы написать детскую кроватку. В качестве альтернативы вы можете хешировать / проверять контрольную сумму с помощью встроенной функции MySQL, такой как MD5 (и использовать только первые символы X, если вам нужен короткий код ваучера). В любом случае вам нужно сделать хеш-функцию ... Я просто буду использовать "Luhn" ниже.

В любом случае вот как будет выглядеть триггер:

delimiter //
CREATE TRIGGER make_voucher_code BEFORE INSERT ON vouchers
FOR EACH ROW
BEGIN
    SET @vcount = @vcount + 1;
    SET NEW.voucher = CONCAT(
        NEW.voucher, 
        CAST(@vcount AS CHAR),
        Luhn(CONCAT(NEW.voucher, CAST(@vcount AS CHAR))));
END;
//
delimeter ;

Затем, в ваших INSERT, вы бы добавили в запрос просто «64352», как вы и предлагали. Триггер добавит остальные.

Лично, если вы или кто-то другой не сможете лучше решить проблему автоинкремента / @ vcount, я все же предпочел бы выполнить транзакцию MySQL, которая лучше справится с задачей, чем хранение всего атомарного и сохранение всего кода вашего приложения на PHP.

0 голосов
/ 12 мая 2011

Или выполните вставку со значением 0, затем получите идентификатор вставки, вычислите значение и обновите запись в.

...