我的表格列是invoiceid(主要AI),invoiceno,purchaseorderno,userid。我认为我不能使用invoiceid,例如:当客户购买2个产品时,2个invoiceid将是差异。所以我决定使用invoiceno,无论何时用户点击订单并且他购买了例如2个产品,他们将拥有相同的invoiceno。我有以下代码:
$invoice = 0000000;
$invoiceno = $invoice + 1;
$sqlString1 = "INSERT INTO invoice
(invoiceno, purchaseorderno, userid)
VALUES ('$invoiceno', '$purchaseorderno', '$userid');";
$result1 = mysqli_query($conn, $sqlString1);
它有效,但发票不能保留为1.当我点击订单时它不会增加。如果我的想法是错误的,建议将不胜感激。
答案 0 :(得分:3)
我会在两张桌子而不是一张桌子里做。
您有invoice
和invoice_item
,其中有一对多关系。
如果您为订单项创建另一个表格,那么所有问题都会消失。
表格发票
id
date
total
status etc...
表invoice_item
id
invoice_id - foreign key
product_id
quantity
etc...
选择它们没问题
SELECT
{fields}
FROM
invoice AS i
JOIN
invoice_item AS l ON i.id = l.invoice_id
WHERE
i.id = :id
依旧......
然后您可以使用发票中的主键和您的所有设置。它也可能更强大(不易破碎)可能更快,从长远来看可能更容易编码等等。
它确实为数据模型增加了一点点复杂性,在执行插入和删除操作时更加谨慎,但是如果你正确设置了外键约束,在插入时使用事务,你应该没问题
<强>更新强>
这是一个DBfiddle(点击它),其中包含一些如何设置forign键以及如何构建基本表关系的示例。我猜对了这些领域你当然可以做任何你需要的改动,添加或删除它们。这只是为了解释它。
CREATE TABLE invoice(
id INT(10) unsigned NOT NULL AUTO_INCREMENT,
total DECIMAL(6,2) unsigned NOT NULL,
email VARCHAR(100),
submission_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY ( id )
) ENGINE=InnoDB;
CREATE TABLE invoice_item(
id INT(10) unsigned NOT NULL AUTO_INCREMENT,
invoice_id INT(10) unsigned NOT NULL,
product_id INT(10) unsigned NOT NULL,
qty INT(3) unsigned NOT NULL,
sub_total DECIMAL(6,2) unsigned NOT NULL,
PRIMARY KEY ( id ),
CONSTRAINT FK_InvoiceItems FOREIGN KEY(invoice_id) REFERENCES invoice(id) ON DELETE CASCADE ON UPDATE CASCADE,
KEY(product_id)
) ENGINE=InnoDB;
只需几个查询示例:
插入发票
#in the example fiddle this is AI #2 so invoice.id=2
INSERT INTO invoice (total,email) VALUES ('100.00','user2@example.com');
插入相关的发票项目
#both of these line items have same invoice,
INSERT INTO invoice_item (invoice_id,product_id,qty,sub_total) VALUES ('2','200','7','70.00');
INSERT INTO invoice_item (invoice_id,product_id,qty,sub_total) VALUES ('2','270','2','30.00');
基本内部联接(选择包含项目及其项目的所有发票)
SELECT
i.*, l.id AS invoice_item_id, l.product_id, l.qty
FROM
invoice AS i
LEFT JOIN
invoice_item AS l ON i.id = l.invoice_id;
计算唯一商品的数量
SELECT
invoice_id, COUNT(id) AS unique_items
FROM
invoice_item
GROUP BY invoice_id;
计算总项目数。你可以求和,sub_total以相同的方式得到总数。如果您愿意,可以删除invoice.total
。在那里计算总数可能会很好,但是当你/更改发票中的项目数时,你还必须更新它。
SELECT
invoice_id, SUM(qty) AS total_items
FROM
invoice_item
GROUP BY invoice_id;
查找没有项目的任何发票(不可能在没有发票的情况下添加带有fk约束的项目,这正是我们想要的)
SELECT
i.*, l.id AS invoice_item_id, l.product_id, l.qty
FROM
invoice AS i
LEFT JOIN
invoice_item AS l ON i.id = l.invoice_id
WHERE
l.id IS NULL;
最后,删除发票,由于这个限制,它会级联并从invoice_item中删除相关项目而不需要额外的工作,换句话说,这些项目会被自动魔术删除。我也发现让数据库进行级联删除要比手动删除它们快得多。
DELETE FROM invoice WHERE id=2;
在此数据模型中,我有按产品分组的invoice_items。因此对于invoice.id#2,我们有两个项目,一个产品ID为#200,这是玩具ufo&#39; s。另一种是#270,它是金属气象气球。 Tiny Tim以7美元的价格获得了7个不明飞行物,价格为70美元,然后他以每个15美元的价格获得了2个气球(我们政府所做的并不便宜)。
好的,那是我当天的DB 101课程。
<强> UPDATE1 强>
基于此错误
无法添加或更新子行:外键约束失败
这实际上是一件好事,它是外键的目的。我会尝试解释
如果你这样做,请插入
INSERT INTO invoice (total,email) VALUES ('100.00','user2@example.com');
这会在invoice
中创建一行,这是插入的目的。现在因为它的自动增量ID,这是第一行id
1
。因为它是第一行,它也是invoice
中唯一的记录。我们都同意这一点,我在新表中插入1行,这使它成为第一行也是唯一一行。它的AI ID为1
现在,如果我尝试插入
INSERT INTO invoice_item (invoice_id,product_id,qty,sub_total) VALUES ('2','200','7','70.00');
此行的invoice_id
为2
,我们刚才说我们有一张id
1
的发票。因此,没有id
2
的发票。这会给你带来同样的错误,因为你试图添加一个invoice_item
而没有它与invoice
相关联,这是我们永远不想要发生的事情。这被称为&#34;孤儿&#34;因为它的父行不存在而排。如果我们允许,我们的数据库可以填写没有发票的发票项目。然后,如果我们稍后添加一个具有其中一个孤立行的id的发票,那么我们只关联不应该关联的内容。这就是为什么这个错误有意义以及为什么它是一件好事。
解决此问题的明显方法是不要插入不属于invoice_items
的{{1}}。
我真的希望这是有道理的。
那么我们如何插入有invoice
的<{1}}?
在PHP中,您希望插入发票然后获取它的ID,然后插入invoice_item。见本页。
http://php.net/manual/en/mysqli.insert-id.php
invoice_items
此处的重要部分是在插入发票项目时使用invoice
。现在,如果要将发票项目添加到之前插入的现有发票中。然后,您只需查询发票,并将其拉出并将其用于新发票项目。
希望有所帮助,享受!