Initial commit: 景耀JY1.0项目
This commit is contained in:
243
生产计划SQL开发文档.md
Normal file
243
生产计划SQL开发文档.md
Normal file
@@ -0,0 +1,243 @@
|
||||
# **车间生产管理SQL开发 - 逐步构建生产计划视图与存储过程**
|
||||
|
||||
## **1. 原始需求与基础查询**
|
||||
|
||||
**目标**:从多个关联表中查询生产数据,并逐步添加计算字段。
|
||||
|
||||
### **1.1 基础数据源**
|
||||
|
||||
涉及三张核心表和视图:
|
||||
|
||||
- `车间生产管理_零件工序_视图`:包含订单号、产品名称、零件名称、工序、数量等。
|
||||
- `车间生产管理工艺_零件工序_任务分配`:包含工序流水号、计划数量、加工数量、计划日期等。
|
||||
- `基础数据_设备工位点检表`:包含设备流水号、工位号、设备名称。
|
||||
|
||||
### **1.2 初始联接查询**
|
||||
|
||||
通过 `工序流水号` 和 `设备流水号` 联接上述三张表。
|
||||
|
||||
sql
|
||||
|
||||
```
|
||||
SELECT dbo.车间生产管理_零件工序_视图.订单号,
|
||||
dbo.车间生产管理_零件工序_视图.产品名称,
|
||||
-- ... 其他字段
|
||||
dbo.基础数据_设备工位点检表.工位号 + N':' + dbo.基础数据_设备工位点检表.设备名称 AS 设备,
|
||||
dbo.车间生产管理_零件工序_视图.数量 AS 订单数,
|
||||
dbo.车间生产管理工艺_零件工序_任务分配.数量 AS 计划数
|
||||
-- ... 其他字段
|
||||
FROM dbo.车间生产管理工艺_零件工序_任务分配
|
||||
INNER JOIN dbo.车间生产管理_零件工序_视图 ON dbo.车间生产管理工艺_零件工序_任务分配.工序流水号 = dbo.车间生产管理_零件工序_视图.工序流水号
|
||||
INNER JOIN dbo.基础数据_设备工位点检表 ON dbo.车间生产管理工艺_零件工序_任务分配.设备流水号 = dbo.基础数据_设备工位点检表.设备流水号
|
||||
```
|
||||
|
||||
## **2. 逐步新增计算字段**
|
||||
|
||||
在基础查询上,根据业务需求分步添加了三个计算字段。
|
||||
|
||||
### **2.1 新增 `状态` 字段**
|
||||
|
||||
**需求**:根据加工数量与计划数量的对比,判断订单状态为“派工中”、“生产中”或“已完成”。
|
||||
|
||||
**逻辑**:
|
||||
|
||||
- **已完成**:加工数量 >= 计划数量
|
||||
- **生产中**:0 < 加工数量 < 计划数量
|
||||
- **派工中**:加工数量 = 0 或 NULL
|
||||
|
||||
**SQL 片段**:
|
||||
|
||||
sql
|
||||
|
||||
```
|
||||
CASE
|
||||
WHEN ISNULL(dbo.车间生产管理工艺_零件工序_任务分配.加工数量, 0) >= dbo.车间生产管理工艺_零件工序_任务分配.数量
|
||||
THEN '已完成'
|
||||
WHEN ISNULL(dbo.车间生产管理工艺_零件工序_任务分配.加工数量, 0) > 0
|
||||
AND ISNULL(dbo.车间生产管理工艺_零件工序_任务分配.加工数量, 0) < dbo.车间生产管理工艺_零件工序_任务分配.数量
|
||||
THEN '生产中'
|
||||
ELSE '派工中'
|
||||
END AS 状态
|
||||
```
|
||||
|
||||
### **2.2 新增 `完成率` 字段**
|
||||
|
||||
**需求**:计算完成率 = (加工数量 / 计划数量) × 100%。
|
||||
|
||||
**SQL 片段**:
|
||||
|
||||
sql
|
||||
|
||||
```
|
||||
CASE
|
||||
WHEN ISNULL(dbo.车间生产管理工艺_零件工序_任务分配.数量, 0) = 0 THEN '0%'
|
||||
ELSE CAST(ROUND(ISNULL(dbo.车间生产管理工艺_零件工序_任务分配.加工数量, 0) * 100.0 /
|
||||
dbo.车间生产管理工艺_零件工序_任务分配.数量, 2) AS DECIMAL(10, 2)) + '%'
|
||||
END AS 完成率
|
||||
```
|
||||
|
||||
### **2.3 新增 `投产时间` 字段**
|
||||
|
||||
**需求**:从 `车间生产管理工艺_零件工艺计划` 表获取 `分配日期`,作为投产时间。
|
||||
|
||||
**实现**:需要 `LEFT JOIN` 新表,通过 `工艺计划流水号` 关联。
|
||||
|
||||
sql
|
||||
|
||||
```
|
||||
-- 新增的 JOIN
|
||||
LEFT OUTER JOIN dbo.车间生产管理工艺_零件工艺计划
|
||||
ON dbo.车间生产管理_零件工序_视图.工艺计划流水号 = dbo.车间生产管理工艺_零件工艺计划.工艺计划流水号
|
||||
|
||||
-- 新增字段
|
||||
CONVERT(varchar(10), dbo.车间生产管理工艺_零件工艺计划.分配日期, 23) AS 投产时间
|
||||
```
|
||||
|
||||
## **3. 创建生产计划视图 (`车间生产管理_生产计划_视图_新`)**
|
||||
|
||||
将上述所有逻辑整合,创建了一个名为 `车间生产管理_生产计划_视图_新` 的视图。
|
||||
|
||||
sql
|
||||
|
||||
```
|
||||
CREATE VIEW dbo.车间生产管理_生产计划_视图_新 AS
|
||||
SELECT dbo.车间生产管理_零件工序_视图.订单号,
|
||||
dbo.车间生产管理_零件工序_视图.产品名称,
|
||||
dbo.车间生产管理_零件工序_视图.零件名称,
|
||||
dbo.车间生产管理_零件工序_视图.工序,
|
||||
dbo.基础数据_设备工位点检表.工位号 + N':' + dbo.基础数据_设备工位点检表.设备名称 AS 设备,
|
||||
dbo.车间生产管理_零件工序_视图.数量 AS 订单数,
|
||||
dbo.车间生产管理工艺_零件工序_任务分配.数量 AS 计划数,
|
||||
CONVERT(varchar(10), dbo.车间生产管理工艺_零件工序_任务分配.计划完成日期, 23) AS 计划完成日期,
|
||||
dbo.车间生产管理工艺_零件工序_任务分配.数量 - dbo.车间生产管理工艺_零件工序_任务分配.加工数量 AS 剩余数,
|
||||
dbo.车间生产管理_零件工序_视图.零件图号,
|
||||
dbo.车间生产管理_零件工序_视图.工序顺序,
|
||||
CONVERT(varchar(10), dbo.车间生产管理工艺_零件工序_任务分配.计划开始日期, 23) AS 计划开始日期,
|
||||
dbo.基础数据_设备工位点检表.设备名称,
|
||||
-- 状态字段
|
||||
CASE
|
||||
WHEN ISNULL(dbo.车间生产管理工艺_零件工序_任务分配.加工数量, 0) >= dbo.车间生产管理工艺_零件工序_任务分配.数量
|
||||
THEN '已完成'
|
||||
WHEN ISNULL(dbo.车间生产管理工艺_零件工序_任务分配.加工数量, 0) > 0
|
||||
AND ISNULL(dbo.车间生产管理工艺_零件工序_任务分配.加工数量, 0) < dbo.车间生产管理工艺_零件工序_任务分配.数量
|
||||
THEN '生产中'
|
||||
ELSE '派工中'
|
||||
END AS 状态,
|
||||
-- 完成率字段
|
||||
CASE
|
||||
WHEN ISNULL(dbo.车间生产管理工艺_零件工序_任务分配.数量, 0) = 0 THEN '0%'
|
||||
ELSE CAST(ROUND(ISNULL(dbo.车间生产管理工艺_零件工序_任务分配.加工数量, 0) * 100.0 /
|
||||
dbo.车间生产管理工艺_零件工序_任务分配.数量, 2) AS DECIMAL(10, 2)) + '%'
|
||||
END AS 完成率,
|
||||
CONVERT(varchar(10), dbo.车间生产管理工艺_零件工艺计划.分配日期, 23) AS 投产时间,
|
||||
dbo.车间生产管理_零件工序_视图.精工期限
|
||||
FROM dbo.车间生产管理工艺_零件工序_任务分配
|
||||
INNER JOIN dbo.车间生产管理_零件工序_视图
|
||||
ON dbo.车间生产管理工艺_零件工序_任务分配.工序流水号 = dbo.车间生产管理_零件工序_视图.工序流水号
|
||||
INNER JOIN dbo.基础数据_设备工位点检表
|
||||
ON dbo.车间生产管理工艺_零件工序_任务分配.设备流水号 = dbo.基础数据_设备工位点检表.设备流水号
|
||||
LEFT OUTER JOIN dbo.车间生产管理工艺_零件工艺计划
|
||||
ON dbo.车间生产管理_零件工序_视图.工艺计划流水号 = dbo.车间生产管理工艺_零件工艺计划.工艺计划流水号
|
||||
```
|
||||
|
||||
### **4. 视图创建后的关键Bug与修复**
|
||||
|
||||
#### **4.1 Bug #1:查询视图时“varchar转换为numeric”错误**
|
||||
|
||||
**原因**:在计算`完成率`字段时,错误地将数字(DECIMAL)与字符串('%')直接拼接,SQL Server无法自动处理类型转换。\
|
||||
**修复**:将计算得到的数字显式转换为字符串(VARCHAR)后再拼接。
|
||||
|
||||
sql
|
||||
|
||||
```
|
||||
-- 错误写法
|
||||
CAST(... AS DECIMAL(10, 2)) + '%'
|
||||
|
||||
-- 正确写法
|
||||
CAST(CAST(... AS DECIMAL(10, 2)) AS VARCHAR(20)) + '%'
|
||||
```
|
||||
|
||||
#### **4.2 Bug #2:存储过程中“列名‘年份’无效”和“modulo运算符不兼容”**
|
||||
|
||||
**原因**:
|
||||
|
||||
1. 最初假设视图包含`年份`和`月份`字段,但实际视图不包含,导致筛选失败。
|
||||
2. 动态SQL中拼接`LIKE`子句时,单引号处理混乱,导致SQL Server将部分字符串和`%`误解析为模运算。
|
||||
|
||||
**最终修复**:
|
||||
|
||||
1. **利用已有字段筛选**:使用视图中的`投产时间`字段进行模糊匹配。
|
||||
|
||||
sql
|
||||
```
|
||||
-- 动态SQL中的WHERE部分
|
||||
WHERE (投产时间 like @月份 + '-%' or 计划完成日期 like @月份 + '-%')
|
||||
```
|
||||
2. **正确拼接动态SQL**:确保参数化查询,避免字符串拼接错误。
|
||||
|
||||
sql
|
||||
```
|
||||
-- 存储过程中正确的拼接和参数传递示例
|
||||
ALTER PROCEDURE [dbo].[车间生产管理_生产计划_查询数据]
|
||||
@月份 nvarchar(50),
|
||||
@零件名称_check bit = null,
|
||||
@零件名称 nvarchar(50) = null,
|
||||
@状态_check bit = null,
|
||||
@状态 nvarchar(50) = null
|
||||
AS
|
||||
BEGIN
|
||||
DECLARE @selectStr NVARCHAR(4000) = 'SELECT * FROM 车间生产管理_生产计划_视图_新 WHERE (投产时间 like @月份 + ''-%'' or 计划完成日期 like @月份 + ''-%'')';
|
||||
|
||||
IF @零件名称_check = 1
|
||||
SET @selectStr = @selectStr + ' AND 零件名称 like ''%'' + @零件名称 + ''%''';
|
||||
|
||||
IF @状态_check = 1
|
||||
SET @selectStr = @selectStr + ' AND 状态 = @状态';
|
||||
|
||||
EXEC sp_executesql @selectStr,
|
||||
N'@月份 nvarchar(50), @零件名称 nvarchar(50), @状态 nvarchar(50)',
|
||||
@月份, @零件_name, @状态;
|
||||
END
|
||||
```
|
||||
|
||||
### **5. 新增 `年` 和 `月` 字段**
|
||||
|
||||
为方便按年月筛选,在最终视图中从`投产时间`(分配日期)中直接提取`年`和`月`两个独立字段。
|
||||
|
||||
**最终视图SQL(含年、月字段)**:
|
||||
|
||||
sql
|
||||
|
||||
```
|
||||
SELECT -- ... 其他字段 ...
|
||||
CASE WHEN dbo.车间生产管理工艺_零件工艺计划.分配日期 IS NOT NULL
|
||||
THEN YEAR(dbo.车间生产管理工艺_零件工艺计划.分配日期)
|
||||
ELSE NULL END AS 年,
|
||||
CASE WHEN dbo.车间生产管理工艺_零件工艺计划.分配日期 IS NOT NULL
|
||||
THEN MONTH(dbo.车间生产管理工艺_零件工艺计划.分配日期)
|
||||
ELSE NULL END AS 月
|
||||
FROM -- ... 表联接 ...
|
||||
```
|
||||
|
||||
这样存储过程可直接使用`WHERE 年 = @年 AND 月 = @月`进行筛选,更为高效。
|
||||
|
||||
### **6. 最终调用示例**
|
||||
|
||||
在应用程序中调用存储过程,传入参数。
|
||||
|
||||
json
|
||||
|
||||
```
|
||||
{
|
||||
"合同编号": "",
|
||||
"合同编号_check": 0,
|
||||
"零件名称_check": 0,
|
||||
"零件名称": "",
|
||||
"产品名称_check": 0,
|
||||
"产品名称": "",
|
||||
"状态_check": 0,
|
||||
"状态": "",
|
||||
"月份": "2025-04"
|
||||
}
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user