2011-09-27 14 views
2

我有一個發票號碼,這個號碼是關聯到一個特殊的文件。這個文件有一個ID,並以漸進的數量和今年形成的,這樣模式和表格設計與auto_increment字段,這不是一個關鍵

222-2011 
223-2011 
224-2011 
... 

每年從1

1-2012 
2-2012 
3-2012 

進步號重啓首先我認爲做一個表with invoice_n,prog_n,year。 prog_n是AUTO_INCREMENT,每年我都會重置它。但是你不能使用不是一個鍵的AUTO_INCREMENT字段。無論如何,我要重置櫃檯,這是不太可取的...

我不能改變ID格式,我必須使用該規則。我能以某種方式獲得高效的設計嗎?

環境是經典的燈泡

非常感謝!

回答

3

擴展在@Marius答案,我會使用觸發器來有MySQL的自動設置invoicenumber像這樣:

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

+0

很漂亮,我did'nt kenw trigers。現在我正在閱讀關於它們的一些文檔,據我瞭解,我可以在不指定特殊字段的情況下執行插入操作。觸發器和DBMS現在關心它。對? – Infrid

+0

您不能通過'NEW'虛擬表格將觸發器鏈接到表格。但是,您可以更改其他表格。 – Johan

3

你可以有一個獨立的id列在發票表auto_increment,並用以下公式填充prog_n觸發:自動

prog_n = id - select max(id) from invoices where year = current_year - 1 

這樣,你的prog_n重置每年而你不知道不需要手動完成。但是,如果您在表格中插入大量發票,這可能是一個性能問題,但我認爲這不會在實踐中發生。

相關問題