先插入采购明细,再创建采购主单
发布时间:2026-06-01 19:19 浏览量:2
一、错误根源分析
Field 'purchase_id' doesn't hava a default value 错误的根本原因是: wms_purchase_detail表中的purchase_id字段被定义为NOT NULL,但在执行INSERT时未提供该字段的值,也未设置默认值。
这个问题属于表结构设计与业务流程不匹配:采购明细必须关联采购主单,但当前流程是先插入采购明细,再创建采购主单,导致插入明细时无法获取purchase_id。
二、完整解决方案
1. 表结构优化(二选一)
方案A:允许purchase_id为空(推荐)
sql
复制
ALTER TABLE wms_purchase_detail
MODIFY COLUMN purchase_id BIGINT COMMENT '关联采购单ID(采购完成前可为空)';
优势:符合业务逻辑(采购明细先于采购主单创建),无需修改业务流程
方案B:设置purchase_id默认值(不推荐)
sql
复制
MODIFY COLUMN purchase_id BIGINT DEFAULT 0 COMMENT '关联采购单ID';
劣势:默认值0无实际业务意义,可能导致数据混淆
2. 优化后的完整业务流程
(1)生成采购需求(无purchase_id限制)
sql
复制
INSERT INTO wms_purchase_detail (
goods_id, goods_name, goods_spec, goods_unit,
purchase_quantity, unit_price, amount, tax_rate, tax_amount
)
SELECT
goods_id,
goods_name,
goods_spec,
goods_unit,
SUM(plan_quantity) AS total_quantity,
MAX(unit_price) AS purchase_price,
SUM(plan_quantity * unit_price) AS total_amount,
MAX(tax_rate) AS tax_rate,
SUM(plan_quantity * unit_price * tax_rate) AS total_tax
FROM wms_order_goods_purchase
WHERE purchase_status = 0
GROUP BY goods_id, goods_name, goods_spec, goods_unit;
(2)创建采购主单并关联明细
sql
复制
-- 2.1 创建采购主单
INSERT INTO wms_purchase_order (supplier_id, purchase_total, create_by)
SELECT
'DEFAULT_SUPPLIER' AS supplier_id, -- 替换为实际供应商ID
SUM(amount) AS total_amount,
'system' AS create_by
FROM wms_purchase_detail
WHERE purchase_id IS NULL;
-- 2.2 获取新创建的采购单ID
SET @new_purchase_id = LAST_INSERT_ID;
-- 2.3 关联采购明细与采购主单
UPDATE wms_purchase_detail
SET purchase_id = @new_purchase_id
(3)反向关联原始订单商品
sql
复制
UPDATE wms_order_goods_purchase ogp
JOIN wms_purchase_detail pd
ON ogp.goods_id = pd.goods_id
AND ogp.goods_spec = pd.goods_spec
SET ogp.purchase_detail_id = pd.detail_id
WHERE ogp.purchase_status = 0;
3. 事务包裹确保数据一致性
sql
复制
START TRANSACTION;
-- 1. 生成采购需求
INSERT INTO wms_purchase_detail (...) SELECT ...;
-- 2. 创建采购主单
INSERT INTO wms_purchase_order (...) SELECT ...;
-- 3. 关联采购明细
UPDATE wms_purchase_detail SET purchase_id = @new_purchase_id WHERE purchase_id IS NULL;
-- 4. 关联原始订单
JOIN wms_purchase_detail pd ON ogp.goods_id = pd.goods_id AND ogp.goods_spec = pd.goods_spec
COMMIT;
三、关键设计调整说明
调整点 实现方式 优势
字段约束 将purchase_id改为可为空 符合业务流程(明细先于主单创建)
事务控制 完整流程包裹在事务中 确保数据一致性,避免部分操作失败导致的脏数据
安全提示:
若使用多线程或多实例环境,LAST_INSERT_ID可能失效,建议改用SELECT MAX(purchase_id)获取最新采购单ID
若需要按供应商拆分采购单,需在GROUP BY中增加supplier_id字段,并循环创建采购主单
四、下一步建议
若需要按供应商生成独立采购单,可补充wms_order_goods_purchase表中是否有supplier_id字段
若采购单价需要根据供应商报价确定,可补充供应商报价表结构
若需要支持部分采购(分批采购),需调整采购状态字段的设计