先插入采购明细,再创建采购主单

发布时间: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字段

若采购单价需要根据供应商报价确定,可补充供应商报价表结构

若需要支持部分采购(分批采购),需调整采购状态字段的设计