使用 SQL 和 PHP 每年为发票编号和不同的结构

问题描述 投票:0回答:2

我是 SQL 的初学者,我试图在没有任何运气的情况下寻找答案。

我想自动生成具有以下区别的发票编号:

  • 我有两种不同的发票结构
  • 我想避免任何编号问题,例如,如果某些内容被更改(例如:1、2、4、5、8、9 ...),不会丢失发票编号
  • 我希望它们每年都被重置,所以每个结构的编号每年都从 1 开始:

例如:ENG_2022_1、ENG_2022_2 ... ENG_2023_1

例如:FR_2022_1、FR_2022_2、FR_2022_3、……FR_2023_1

我想过设置一个自动递增的字段,但是除非有解决方法,否则这不适用于结构和年份区分?

另一个解决方案是在开具发票之前获取年份和结构,并在编号之前将其与发票编号的 SQL MAX 进行比较,但我不确定该解决方案有多好?

任何帮助将不胜感激

php sql auto-increment invoice sql-max
2个回答
0
投票

自动递增列的使用似乎很明显,但是,在您的情况下,您希望在每年年初重新开始编号,因此应该提供一些东西。

我会在发票表中为此至少创建四列:

  • invoice_id: 这是自增列
  • invoice_date: 你可以从这个日期开始用
    YEAR(invoice_date)
    得到年份。
  • invoice_sequence:
    FR
    ENG
    .
  • invoice_number: 包含实际发票号。

要创建发票编号,您需要知道当年序列中的发票数量。这可以在单独的查询中检索:

SELECT
  COUNT(*) AS invoice_count
FROM
  invoice_table
WHERE
  invoice_sequence = :sequence AND
  YEAR(invoice_date) = YEAR(:date);

在此查询中,

:sequence
:date
是占位符,用于绑定您要查找的值

之后您可以插入实际发票。这是此类插入物的模型:

INSERT INTO
  invoice_table
  (invoice_date,
   invoice_sequence,
   invoice_number,
   ......)
VALUES
  (:date,
   :sequence, 
   CONCAT(:sequence, '_', YEAR(:date), '_', :invoiceCount),
   ......)

在此查询中,

:date
:sequence
:invoiceCount
是占位符,用于绑定我们已知的值。请注意,在某些情况下,您不能重复相同的占位符名称。在那种情况下,使用像
:name1
:name2
这样的东西,或者只是
?
.

请注意,您可以将查询以检索插入查询中的计数作为子查询。为了更好的可读性,我在这里没有这样做。


0
投票

我建议您分别存储序列、年份和数字。

为此创建三列:

invoice_number   INTEGER,
invoice_year     INTEGER,
invoice_sequence VARCHAR(4)

并获得最终价值

SELECT CONCAT(invoice_sequence, '_', invoice_year, '_', invoice_number) inv_full number
FROM MY_INVOICES

之后创建将在插入时自动生成发票编号的触发器:

CREATE TRIGGER GENERATE_INVOICE_NUMBER
BEFORE INSERT
ON MY_INVOICES FOR EACH ROW
BEGIN
    SELECT IFNULL(MAX(invoice_number), 0) + 1
    INTO new.invoice_number
    FROM MY_INVOICES
    WHERE invoice_year = new.invoice_year
    AND invoice_sequence = new.invoice_sequence;
END

此处函数

MAX
用于获取指定序列和年份的先前数字的最大值,以考虑发票删除的可能性并避免违反数字唯一性。

© www.soinside.com 2019 - 2024. All rights reserved.