我有发票号码;该号码与一份特殊文件相关联。该文档有一个 id,由渐进数字和当前年份组成,如下所示
222-2011
223-2011
224-2011
...
每年累进数字从1重新开始
1-2012
2-2012
3-2012
一开始我想制作一张包含invoice_n、prog_n、year的表格。 prog_n 是自动递增的,每年我都会重置它。但是您不能使用不是键的 AUTO_INCRMENT 字段。反正我也要重置计数器,这个不太推荐。
我无法更改id格式;我必须使用这个规则。我可以以某种方式进行有效的设计吗?
环境是经典的LAMP
您的发票表中可以有一个单独的
id
列,其中包含 auto_increment
,以及一个使用以下公式填充 prog_n
的触发器:
prog_n = id - select max(id) from invoices where year = current_year - 1
这样,您的
prog_n
每年都会自动重置,而无需手动执行。但是,如果您在表中插入大量发票,可能会出现性能问题,但我认为实际上不会发生这种情况。
扩展Marius的答案,我将使用触发器让MySQL自动设置发票号码,如下所示:
DELIMITER $$
CREATE TRIGGER bi_invoices_each BEFORE INSERT ON invoices FOR EACH ROW
BEGIN
DECLARE lastest_invoice_number VARCHAR(20);
DECLARE numberpart INTEGER;
-- find lastest invoicenumber in the current year.
SELECT COALESCE(max(invoicenumber),0) INTO lastest_invoice_number
FROM invoice
WHERE invoice_date >= MAKEDATE(YEAR(NEW.invoice_date) ,1)
AND invoice_date < MAKEDATE(YEAR(NEW.invoice_date)+1,1);
-- extract the part before the '-'
SET numberpart = SUBSTRING_INDEX(lastest_invoice_number,'-',1)
SET NEW.invoicenumber = CONCAT(numberpart+1,'-',YEAR(NEW.invoice_date));
END $$
DELIMITER ;
请注意,您无法在
before
触发器中访问自动递增的 id;after
触发器中才能执行此操作,但在那里您无法更改任何值,因此需要一些技巧。invoice_date
,以便可以使用该字段上的索引。
参见:
http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_substring-index
http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_makedate