75 lines
3.8 KiB
MySQL
75 lines
3.8 KiB
MySQL
|
|
-- =============================================================================
|
|||
|
|
-- 借库转交 · 粒度下沉到明细行(部分转交)
|
|||
|
|
--
|
|||
|
|
-- 背景(业务方推翻上一轮约束)
|
|||
|
|
-- 上一轮按「一张单同时只能有一个持有人」实现了**整单转交**,并把「单内出现
|
|||
|
|
-- 多个持有人」当作 bug 去修。业务方验收后明确纠正:
|
|||
|
|
-- 物理现场经常只转交部分工具(借了 2 件,只把 1 件转给别人),
|
|||
|
|
-- **单内多持有人才是符合现实的正常状态**。
|
|||
|
|
-- 故转交粒度从 borrow_no 下沉回 trans_borrow.id(明细行)。
|
|||
|
|
--
|
|||
|
|
-- ---------------------------------------------------------------------------
|
|||
|
|
-- 本次改动的实质
|
|||
|
|
-- 代码层:transfer_borrow / accept_transfer 只操作**一行**明细,
|
|||
|
|
-- 唯一性约束从「单号最多一条 PENDING」改为「明细行最多一条 PENDING」。
|
|||
|
|
-- 数据层:**无需改动任何表结构** —— borrow_id(明细行)本就是流水的主键
|
|||
|
|
-- 关联列,borrow_no 继续保留作单据归属与展示分组用。
|
|||
|
|
-- 仅补一个复合索引,支撑「按明细行查待接收流水」这一新查询路径。
|
|||
|
|
--
|
|||
|
|
-- ★ 为什么不需要新的列
|
|||
|
|
-- 转交粒度既然回到明细行,覆盖范围就是 borrow_id 指向的那一行本身 ——
|
|||
|
|
-- 不需要额外的「覆盖清单」来表达范围,borrow_no 退化为分组/展示用途。
|
|||
|
|
--
|
|||
|
|
-- ★ 存量数据不动(业务方选择)
|
|||
|
|
-- BOR-20260917-0001 的「测试 / 杜邢宸」双持有人状态予以保留:
|
|||
|
|
-- 它现在不再是 bug,而是「部分转交」的正常业务形态。
|
|||
|
|
--
|
|||
|
|
-- 幂等:带 IF NOT EXISTS,可重复执行。
|
|||
|
|
-- 执行:docker exec -i inventory_db psql -U test -d inventory_system < 本文件
|
|||
|
|
-- =============================================================================
|
|||
|
|
|
|||
|
|
BEGIN;
|
|||
|
|
|
|||
|
|
-- 支撑「该明细行是否已有待接收流水」的唯一性检查,以及按明细行批量取待接收
|
|||
|
|
CREATE INDEX IF NOT EXISTS ix_trans_borrow_transfer_borrow_status
|
|||
|
|
ON trans_borrow_transfer (borrow_id, status);
|
|||
|
|
|
|||
|
|
COMMENT ON COLUMN trans_borrow_transfer.borrow_no IS
|
|||
|
|
'借用单号。仅用于单据归属与列表分组展示;转交的**覆盖范围**是 borrow_id 指向的单个明细行';
|
|||
|
|
COMMENT ON COLUMN trans_borrow_transfer.borrow_id IS
|
|||
|
|
'转交目标明细行ID(trans_borrow.id)。转交粒度 = 明细行,一行最多一条待接收流水';
|
|||
|
|
|
|||
|
|
COMMIT;
|
|||
|
|
|
|||
|
|
|
|||
|
|
-- =============================================================================
|
|||
|
|
-- 执行后核对
|
|||
|
|
-- =============================================================================
|
|||
|
|
\echo '--- 1) 复合索引已就位 ---'
|
|||
|
|
SELECT indexname FROM pg_indexes
|
|||
|
|
WHERE tablename = 'trans_borrow_transfer'
|
|||
|
|
AND indexname = 'ix_trans_borrow_transfer_borrow_status';
|
|||
|
|
|
|||
|
|
\echo '--- 2) 存量流水(borrow_id / borrow_no / status)---'
|
|||
|
|
SELECT id, borrow_id, borrow_no, status, from_user_name, to_user_name
|
|||
|
|
FROM trans_borrow_transfer ORDER BY id;
|
|||
|
|
|
|||
|
|
\echo '--- 3) 各明细行的待接收流水数(应全部 <= 1)---'
|
|||
|
|
SELECT borrow_id, count(*) AS 待接收数
|
|||
|
|
FROM trans_borrow_transfer WHERE status = 'PENDING'
|
|||
|
|
GROUP BY borrow_id HAVING count(*) > 1;
|
|||
|
|
|
|||
|
|
\echo '--- 4) 单内多持有人的单号(现在属正常业务形态,不再视为异常)---'
|
|||
|
|
SELECT borrow_no, count(DISTINCT current_holder_id) AS 持有人数,
|
|||
|
|
string_agg(DISTINCT coalesce(current_holder_name,'NULL'), ', ') AS 持有人
|
|||
|
|
FROM trans_borrow WHERE is_returned = FALSE
|
|||
|
|
GROUP BY borrow_no HAVING count(DISTINCT current_holder_id) > 1;
|
|||
|
|
|
|||
|
|
|
|||
|
|
-- =============================================================================
|
|||
|
|
-- 回滚段
|
|||
|
|
-- =============================================================================
|
|||
|
|
-- BEGIN;
|
|||
|
|
-- DROP INDEX IF EXISTS ix_trans_borrow_transfer_borrow_status;
|
|||
|
|
-- COMMIT;
|