0

我正在使用 mysql/php。

我的桌子看起来像

id (int autoincrement)  
voucher(varchar 25)

我正在生成代码为的优惠券代码:

  • 1 个随机数(例如 64)
  • 1 个固定数字(例如 352)
  • id 字段的值 (1,2,3,4,5...)
  • 1 个校验位(luhn 算法)。

使用 php 执行此操作的明显问题是我必须进行选择,获取下一个自动增量值,计算代码,插入,此时可能已插入另一行。

相反,我想做的是,

去做insert into vouchers (voucher) value('64352')并让它产生我的其余部分。

我怎样才能做到这一点?功能/触发器?

4

2 回答 2

1

如果您使用 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
}

编辑/添加:

既然您提到了触发器,我对此进行了研究并相信它是可行的。几个问题。

  1. 从触发器访问“下一个自动增量 ID”......我不知道这样做的“好”方法。在 INSERT 查询中,您只能访问 NEW 而不是 OLD(现有行)值(请参阅触发器语法)。我在示例中所做的只是在服务器上维护一个单独的计数器@vcount。要将此值初始化为当前的 ID,您只需执行“SET @vcount = 42;”

  2. 卢恩算法。您必须将其实现为 SQL 函数。这是您可以从中借鉴的 SQL 中的 Luhn 验证器。或者,您可以使用诸如 MD5 之类的本机 MySQL 函数进行哈希/校验和(如果您需要简短的凭证代码,则仅使用前 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”。触发器将附加其余部分。

就个人而言,除非您或其他人可以更好地解决 autoincrement/@vcount 问题,否则我仍然更喜欢执行 MySQL 事务,这将比保持一切原子性并将所有应用程序代码保留在 PHP 中做得更好。

于 2011-05-12T01:00:01.457 回答
0

或者使用值 0 进行插入,然后获取插入 id,计算值并更新记录。

于 2011-05-12T01:02:54.957 回答