简介:一份面向ERP实施顾问、数据管理专员及企业信息化骨干的专题演示文稿,围绕主数据与业务数据的关系展开。内容先梳理数据管理实施方法,从Aris流程解读、业务访谈、方案设计到系统测试与方案落地;再以总体业务数据流串联项目管理、研发、工艺、采购、库存、生产、销售、财务等环节。17页PPT结合生产订单、销售订单、CRM商机、维修工单、物资管理等案例,拆解物料主数据、BOM、工艺路线、价格、客户、供应商、会计科目等在发料、报工、调拨、开票、应收应付等动作中的传递。资源为单个pptx文件,大小164KB,已有43人学习。内容还汇总了MMQM、PP、SD、FICO模块典型问题及对策,如删除采购信息记录、采用单车BOM、定制备品备件专用订单类型、统一会计科目等,对提升ERP主数据治理水平有直接参考价值。
1. 豪华版ERP主数据与业务数据关系:17页PPT背后的数据治理命题
老板把一个"豪华版ERP主数据与业务数据关系(17页).pptx"丢给我时,我第一反应是模板做得真漂亮,第二反应是这17页到底要讲清什么。做过ERP实施和运维的人都明白:主数据和业务数据的关系从来不是画一张ER图就能交差的。主数据是物料、客户、供应商、会计科目这些"名词",业务数据是订单、发货单、库存流水、财务凭证这些"动词";关系理不顺,MRP跑出来的需求就是错的,库存账实不符永远是玄学,财务和供应链对账能吵一整晚。这篇内容不评价PPT本身,而是把这个主题拆成能照做的数据治理方案:关系怎么建模、字段怎么落、SQL怎么查、坑在哪、以及如何让这份关系文档不只是交付物,而是能持续校验的规则。适合ERP实施顾问、数据专员和数据治理新手照着复现。
2. 从物料编码到库存流水:主数据与业务数据的本质分工
2.1 主数据是"名词",业务数据是"动词":两条链路的建模差异
先给一个判断标准:如果一条数据在多个业务流程里被重复引用、变化频率低、删除时必须考虑历史单据引用,它大概率是主数据。物料、客户、供应商、会计科目、成本中心、利润中心、仓库、资产,都属于主数据。你在SAP里做ABAP资产主数据屏幕增强,改的是资产主数据的屏幕字段,而不是资产业务凭证;你在ERP库存场景里写高并发解决方案,并发压力全在库存业务流水表上,物料主数据本身不会因为一秒十笔过账而产生竞争。这就是主数据和业务数据最直观的差别:主数据是维度,是业务数据的地基;业务数据是事实,是地基上盖起来的房子。
从建模看,主数据和业务数据走的是两条链路。主数据表的做法是:唯一编码做主键,加状态字段和有效期间隔(valid_from / valid_to),用"逻辑删除"代替物理删除,保证历史单据还能通过时间维度追溯当时的引用关系。业务数据表的做法是:用"单据号+行项目号"做联合主键,业务日期跟随发生时间只增不改,数量金额只允许追加或冲销,不允许直接UPDATE历史记录。如果不懂这个区别,最容易翻车的就是把主数据当成普通表做物理删除——删掉一个物料编码,结果三年前的生产订单全部变成黑匣子,下游对账直接崩。
还有一个常被问到的概念:元数据和主数据不是一回事。元数据是"描述数据的数据",回答"这个字段叫什么、什么类型、哪个系统来的";主数据是"被引用的基础实体数据",回答"这个客户是谁、这个物料是什么"。你梳理ERP主数据与业务数据关系时,一定会先做元数据登记,但元数据清单只是第一步,真正的核心是把主数据实体和业务数据实体之间的引用关系、引用层级、同步机制画清楚。
2.2 关系映射的三种典型结构:一对多、多对多、递归引用
把ERP里常见的关系归纳一下,无外乎三种结构。
第一种是一对多,这是最常见的关系。一个客户下有多张销售订单,一个物料下有多条库存收发货记录,一个采购订单头下有多行采购行项目。落到数据库里,就是在"多"的那一方(业务数据表)保存"一"的那一方(主数据表)的主键作为外键。查询方向也由此确定:从订单表带出客户名称,用JOIN订单表引向客户表;反过来从客户看他的全部订单,用WHERE客户编码查订单表。
第二种是多对多,需要中间表承接。典型场景是物料与供应商的关系:一个物料可以有多家合格供应商,一个供应商能供多个物料。ERP里通常把这种关系放在采购信息记录或货源清单里,它具备部分主数据特征——相对稳定、被采购业务引用,所以一般归入主数据扩展。另一个多对多是BOM(物料清单)中成品件与原材料的关系,这在SAP/用友里属于工程主数据,一条BOM行引用子件物料,但子件物料本身也是主数据。
第三种是递归引用,在同一个主数据实体内部自关联。最典型的是BOM的父子层级:一个组装件可以当子件被更上级BOM引用,同时它自己也能引用下一级零件。还有会计科目表:一级科目1001"应收账款"下有二级科目100101"客户A",100102"客户B",它们都在同一张科目主数据表里通过"上级科目编码"字段挂起来。递归引用最麻烦的坑是死循环——A引用B,B引用C,C又引用A,跑MRP时直接陷入无限循环。所以设计递归主数据表时,必须预留"层级号"字段并限制最大展开层数(常见做法是控制在20层以内),同时做环路检测。
2.3 用ER模型落一个最小案例:客户、订单、发货单的关系与字段
空谈关系不如直接建模。下面用一个最精简的销售到发货场景,展示主数据和业务数据在表结构上的差别。这是我在给企业做数据治理方案时常用的最小骨架,所有ERP的进销存链路都能套进去。
-- 客户主数据:编码唯一,状态+有效期间隔是主数据标配 CREATE TABLE mdm_customer ( customer_code VARCHAR(20) PRIMARY KEY, -- 业务主键,全局唯一 customer_name VARCHAR(100) NOT NULL, customer_group VARCHAR(20), -- 客户组:分销/直销/电商 status CHAR(1) DEFAULT 'A', -- A=有效,I=失效 valid_from DATE NOT NULL, valid_to DATE DEFAULT '9999-12-31', change_time TIMESTAMP -- 最后变更时间,用于增量同步 ); -- 销售订单:业务数据,主键是单据号+行号,引用客户主数据 CREATE TABLE o2c_sales_order ( order_id VARCHAR(30) NOT NULL, -- 单据号,如SO20240701001 line_no INT NOT NULL, customer_code VARCHAR(20) NOT NULL, material_code VARCHAR(20) NOT NULL, order_qty DECIMAL(15,3) NOT NULL, order_date DATE NOT NULL, status VARCHAR(10) DEFAULT 'OPEN', -- OPEN/COMPLETED/CANCELLED PRIMARY KEY (order_id, line_no), CONSTRAINT fk_order_customer FOREIGN KEY (customer_code) REFERENCES mdm_customer (customer_code) ); -- 发货单:引用订单行,数量和状态与订单形成勾稽关系 CREATE TABLE o2c_delivery ( delivery_id VARCHAR(30) NOT NULL, line_no INT NOT NULL, order_id VARCHAR(30) NOT NULL, order_line_no INT, delivered_qty DECIMAL(15,3) NOT NULL, delivery_date DATE NOT NULL, PRIMARY KEY (delivery_id, line_no), CONSTRAINT fk_delivery_order FOREIGN KEY (order_id, order_line_no) REFERENCES o2c_sales_order (order_id, line_no) );逻辑说明:客户主数据表用customer_code做业务主键而不是自增整数主键,是因为ERP集成场景里,外部系统、Excel导入、报表平台都需要看到并引用这个编码。status配合valid_from/valid_to实现"软删除+有效期控制",这样即使客户被标记失效,历史订单仍然能通过订单日期判断当时该客户是否有效。销售订单表用(order_id, line_no)联合主键,这是业务数据的通用做法——一张订单头对应多行物料,行项目才是真正引用物料主数据的层级。发货单引用销售订单的联合主键,形成"客户→订单→发货"的单据链。
参数说明:状态字段用CHAR(1)存A/I比存中文"有效/失效"更省空间,且便于写校验条件和建索引。valid_to默认9999-12-31是行业惯例,代表"无限期有效";如果主数据有正式失效日期,再改成真实日期。这里的唯一约束只做演示,实际用Oracle或SAP时,外键是否启用需要看ERP模块配置——很多老ERP为了性能不建物理外键,关系一致性靠应用层维护,这就引出后面章节的校验问题。
3. 把17页PPT变成可复现的关系梳理方法:三张表模板与字段设计
3.1 主数据清单表:实体、编码规则、状态、有效期的字段怎么定
既然要梳理ERP主数据与业务数据的关系,第一步是把主数据实体枚举全面。很多项目从ERP里导出了几十张表,却没有一张"主数据清单"总表,导致关系图画到一半发现漏了利润中心。我一般会先建一张主数据清单表,字段这样设计:
| 字段 | 含义 | 示例/规则 |
|---|---|---|
| 实体类型 | 主数据分类 | 客户/供应商/物料/会计科目/成本中心/利润中心/资产/仓库 |
| 实体代码 | 表名或对象名 | KNA1(SAP客户主数据)、MDM_CUSTOMER |
| 编码规则 | 编码生成规范 | 物料编码定长20位,前三段分别为大类2位+中类4位+流水8位 |
| 状态字段 | 启用/冻结/失效 | A=启用,I=失效,B=冻结 |
| 有效期字段 | 生效起止 | valid_from / valid_to |
| 来源系统 | 主数据的权威来源 | SAP MDG、用友U8、自建MDM |
| 下游引用数 | 被哪些业务表引用 | 销售订单、采购订单、生产订单 |
| 负责人 | 数据Owner | 供应链部(物料)、财务部(科目) |
这张清单表的价值在于:让你在梳理关系前先确认"哪些实体够资格叫主数据"。判断标准就三条——是否跨流程共享、是否被多张单据引用、是否相对稳定。像"客户联系人"这类数据,如果只被CRM使用,不被ERP单据引用,就不应该出现在这份17页PPT的主数据清单里,否则会把关系图撑得很乱。
编码规则字段最容易被人忽略,但它决定了业务数据怎么引用主数据。常见问题有:物料编码有的带前导零,有的不带;客户编码在销售ERP里是6位,在财务共享系统里是8位。整理主数据清单时,我会把编码规则写成"定长、无含义、含校验位"或"分段有含义",并标注源系统实际格式,后面做引用匹配时用得上。
3.2 业务数据清单表:单据类型、流水号、引用主数据的键怎么设计
业务数据清单是第二张表,它不写具体业务字段,而是记录"每一类业务单据在哪个层级引用哪些主数据"。这张表设计得好,后面画关系图就是照单抄的事。
| 字段 | 含义 | 示例 |
|---|---|---|
| 单据类型 | 业务对象分类 | 销售订单/采购订单/生产领料单/库存盘点单/财务凭证 |
| 单据表名 | 物理表或视图 | VBAK(销售订单头)、VBAP(销售订单行) |
| 主键结构 | 单据号+行号,还是单据号+序号 | 订单头主键:VBELN;订单行主键:VBELN+POSNR |
| 引用层级 | 头引用/行引用/头+行列引用 | 订单头引用客户;订单行引用物料 |
| 主数据引用字段 | 具体外键字段名 | KUNNR(客户编号)、MATNR(物料编号) |
| 业务时间字段 | 单据日期/过账日期 | ERDAT(创建日期)、AUFDT(过账日期) |
| 台账保留周期 | 在线保留时长 | 5年归档,历史表保留10年 |
这里要特别强调"引用层级"。一张销售订单,头引用客户、售达方、送达方、销售组织;行引用物料、工厂、库存地点、计量单位。梳理时必须按层级写清楚,否则关系图会在"订单-客户"这一层画完就停了,漏掉"订单行-物料"这个最关键的关系。而MRP主数据介绍里反复强调的BOM展开、独立需求转化为相关需求,依赖的正是"生产订单行-组件物料"的引用关系。
业务数据清单里还要记录"是否允许跨系统引用"。比如你做了本地ERP和自建MDM的集成,客户主数据在MDM里生成,业务单据在ERP里录入,ERP的客户表就是主数据的一个副本。这种情况下,业务数据清单要增加一列"主数据来源表",否则后期排查数据不一致时,你根本不知道订单引用的KUNNR到底该和哪张表的编码比对。
3.3 关系矩阵表:来源系统、引用关系、同步方式与校验规则
第三张表是整个17页PPT的灵魂——关系矩阵。如果说前面两张是点,这张就是把点连成线的边。
| 源主数据实体 | 目标业务数据实体 | 关系类型 | 引用字段映射 | 同步方式 | 校验规则 |
|---|---|---|---|---|---|
| 客户(KNA1/MDM_CUSTOMER) | 销售订单头(VBAK) | 1:N | KUNNR = VBAP-KUNNR | 实时接口 | 不允许订单引用失效客户 |
| 物料(MARA/MDM_MATERIAL) | 销售订单行(VBAP) | 1:N | MATNR = VBAP-MATNR | 实时接口 | 订单行物料必须在物料主数据中启用销售状态 |
| 供应商(LFA1/MDM_VENDOR) | 采购订单头(EKKO) | 1:N | LIFNR = EKKO-LIFNR | 实时接口 | 采购订单不允许引用冻结供应商 |
| 会计科目(SKA1) | 财务凭证明细(BSEG) | 1:N | HKONT = BSEG-HKONT | 批处理+实时 | 科目必须处于记账期内 |
| 物料(MARA) | BOM组件(MAST/STPO) | N:N | MATNR(父件) ↔ MATNR(子件) | 批处理 | BOM展开层级≤20,无回路 |
关系矩阵里,"同步方式"和"校验规则"是落地关键。同步方式决定了主数据变更多久能反映到下游业务单据:客户创建后马上要下单,用实时接口;科目变更涉及财务月结,可以走批处理但必须保证日清日结。校验规则是后面做数据质量检查的蓝图,宁可先在矩阵里多写几条,也不要等数据对不上时再想。
这张矩阵还有个额外价值:当你的ERP关系梳理干净后,想接本地ERP+RAG+LLM做产品检索,直接把矩阵喂给模型,它才知道"客户编码"应该去MDM_CUSTOMER里查、而不是去订单表里猜。很多RAG项目翻车,不是因为模型不行,而是底层数据关系本身就没梳理过。
4. 关系梳理实操:从Oracle/SAP/用友导出数据做关系分析
4.1 导出主数据与业务数据的标准查询脚本(SQL)
关系矩阵画完之后,必须用真实数据验证。我见过太多17页PPT里画的关系图,和底层数据库表字段完全对不上——PPT讲的是"订单引用客户",实际订单表里根本没有客户编码字段,客户名称直接REDUNDANT地冗余在订单表里。所以这个阶段的动作是:按矩阵逐条导出主数据表和业务数据表,检查引用字段是否真实存在。
下面用Oracle EBS的常见表结构做示例。不同ERP的表名不同,但查询逻辑通用:主数据表用编码做主键,业务数据表通过外键字段LEFT JOIN主数据表。
-- 导出客户主数据:Oracle EBS 客户主表 SELECT customer_id, customer_number, customer_name, nvl(status, 'A') AS status, creation_date, last_update_date FROM ar.hz_customers WHERE nvl(status, 'A') = 'A'; -- 导出销售订单头,关联客户主数据,检查外键是否都能匹配 SELECT ord.order_number, ord.book_date, ord.sold_to_customer_id, cus.customer_number, cus.customer_name FROM oe.oe_order_headers_all ord LEFT JOIN ar.hz_customers cus ON ord.sold_to_customer_id = cus.customer_id WHERE ord.book_date >= DATE '2024-01-01';逻辑说明:第一段查询客户主数据,用NVL把空状态当成'A'过滤,保证只导出有效客户。第二段是关系验证查询,重点看sold_to_customer_id能不能在客户主表里匹配上。LEFT JOIN保证所有订单都出现在结果里,如果customer_number是NULL,说明存在孤儿引用。
参数说明:Oracle里DATE '2024-01-01'是标准日期字面量,不要写成TO_DATE('2024-01-01','YYYY-MM-DD'),前者可读性更好。customer_id是内部ID,customer_number是业务编码,做关系分析时尽量输出业务编码,方便非技术人员看懂。
如果你面对的是SAP系统,主数据表KNA1存客户主数据、VBAK存销售订单头、VBAP存销售订单行。查询逻辑一样:VBAK的KUNNR引用KNA1的KUNNR,VBAP的MATNR引用MARA的MATNR。用友U8的客户档案在Customer表,销售订单头在SaleOrder,也是同一个套路。关键不是背表名,而是先跑通"主表LEFT JOIN子表"这条验证思路。
4.2 用Python检查引用完整性与孤儿数据
SQL导出只是第一步,数据量一上来,眼睛看不完,必须用脚本批量检查。我这里用Python+pandas做最经典的"孤儿数据"扫描:确认业务数据里引用的主数据编码,在主数据表里是否真正存在。
import pandas as pd # 读取导出的主数据与业务数据 # 注意:编码字段全部按字符串读取,防止前导零丢失 customer_df = pd.read_csv('mdm_customer.csv', dtype={'customer_code': str}) order_df = pd.read_csv('o2c_sales_order.csv', dtype={'customer_code': str}) # 左连接并标记孤儿记录:业务数据引用了主数据中不存在的编码 merged = order_df.merge( customer_df[['customer_code']], on='customer_code', how='left', indicator=True ) orphan = merged[merged['_merge'] == 'left_only'] print(f'孤儿订单行数: {len(orphan)}') if not orphan.empty: orphan.to_csv('orphan_orders.csv', index=False)逻辑说明:dtype={'customer_code': str}把编码列强制转成字符串,避免Excel导出时物料编码变成科学计数法或数字格式丢前导零。indicator=True会让merge结果多一列_merge,left_only表示左侧的订单表有没有在客户主数据表中匹配上的行,这些就是孤儿数据。输出文件和打印计数可以让你在17页PPT里直接写"订单引用客户匹配率99.86%,发现15条孤儿记录"这类有说服力的数字。
参数说明:如果主数据表有2万条、业务数据有60万条,这个脚本运行时间在几秒内。如果数据量到千万级,建议加一个条件过滤,比如只检查本年度业务单据,避免每次全量扫描。还有一个可调参数是how='left'——如果你想知道"客户主数据里有哪些客户从来没下过单",改成how='right'即可。
4.3 生成关系图与文档:从PowerDesigner到draw.io的落地
数据验证通过后,要把关系可视化。常用做法有三种,按团队条件选。
第一种,直接用数据库建模工具反向生成。Oracle SQL Developer的数据模型器、PowerDesigner都能连接ERP数据库,选择若干表后自动生成外键关系图。好处是准——图里的实线虚线都是真实外键;坏处是ERP表太多,直接把几百张表扔进来会画成一团乱麻。所以我通常只选择关系矩阵里列出的核心表,控制在15张以内。
第二种,用draw.io手工画分层图。我习惯画三层:最底层是主数据实体(客户、物料、供应商、科目),中间层是业务单据头(订单、采购单、生产订单、凭证头),最上层是单据行/流水(订单行、库存过账行、凭证明细)。层与层之间用带箭头的连线表示引用关系,线上标注"KUNNR=VBAK-KUNNR"。这样画出来的图,业务人员看得懂,开发人员也能照图定位字段。
第三种,直接生成HTML/PDF关系文档。把关系矩阵导出成口袋书,每个主数据实体一节,后面跟着"被哪些业务数据引用、引用字段是什么、校验规则是什么"。这种文档比PPT更实用,因为对口人员可以在系统报错时快速查"这个物料被哪些单据引用,为什么不能删"。
落到你的17页PPT交付时,我的建议是:前5页放主数据清单和业务数据清单,中间7页放关系图(一张总览+六张链路:销售到收款、采购到付款、生产到成本、库存到存货、资产到折旧、总账到报表),最后5页放校验规则和问题清单。这样每页都有干货,不是套模板凑数。
5. 数据关系梳理的5个坑:编码不一致、孤儿数据、状态穿越与同步延迟
这一章直接给血泪经验。以下5个问题,几乎每个ERP数据治理项目里都至少中两条。
坑1:编码前导零丢失
现象:业务系统导出的客户编码是001234,Excel打开后自动变成1234,再导入分析平台后匹配不上主数据,报"无效客户编码"。
原因:Excel默认把纯数字列当数值处理,前导零被吃掉。这不是ERP的错,是数据导出导入环节的格式问题,但最终会表现为"主数据和业务数据对不上"。
解决:导出的CSV/Excel在生成时就把编码列设为文本格式,Python读取时用dtype={'customer_code': str}强制转字符串;如果已经丢了,用zfill(6)补零还原。最稳妥的做法是固定编码长度,物料编码20位、客户编码6位,从源头杜绝歧义。
坑2:物理删除了主数据
现象:某物料因停产被管理员从ERP里物理删除,半年后一张历史采购订单在报表里显示物料名称为空,月度对账时这笔采购无法匹配到物料成本。
原因:主数据的物理删除是灾难性的。业务单据永远引用历史,主数据一旦物理消失,所有历史单据都成了孤儿。很多开发人员图省事直接DELETE,而不是置状态字段为'I'加有效期截止。
解决:所有主数据表一律禁止物理删除,只允许逻辑删除(status改'I')并设置valid_to为删除当天。如果历史原因已经删了,需要从备份表恢复并标记为失效状态;恢复不了的话,在关系矩阵中记录该编码为"历史失效编码",报表查询时用LEFT JOIN并在缺失时显示编码本身。
坑3:状态穿越——单据引用了未来才生效的主数据
现象:一张销售订单日期是2024-07-01,但订单引用的客户主数据valid_from是2024-08-01。账务月结时财务发现这笔订单的客户信用评估还没上线,导致风险敞口漏判。
原因:主数据的有效期设置错误,或者业务系统允许录入未来生效的主数据。更隐蔽的原因是把业务单据日期手工改到过去或未来,绕过有效期校验。
解决:在业务单据保存触发器或应用层校验里增加条件:业务日期 BETWEEN 主数据.valid_from AND 主数据.valid_to。像Oracle可以建BEFORE INSERT触发器,发现状态穿越就抛出异常。参数上,主数据的valid_to默认9999-12-31,但valid_from一定要在单据录入时实时校验。
坑4:主数据同步延迟导致新单据引用旧属性
现象:MDM系统改了客户付款条件,但ERP本地客户表继续保存旧数据。当天新单据按旧付款条件执行,一个月后对账发现多扣了两个点的现金折扣。
原因:主数据在MDM侧更新了,但ERP的本地副本同步任务延迟6小时,或者接口失败后没有重推机制。远程审核ERP单据时,审核界面展示的客户名称、付款条件都是从本地副本读的,同步没跑,审核就是看黑匣子。
解决:给主数据表增加last_update_date字段,增量同步只取last_update_date > 上次同步时间的记录。同步完成后,做一次比对脚本:对比MDM和ERP两边主数据表的MD5或逐字段diff,不一致的自动告警。同步频率要写入关系矩阵,客户、物料这类每天至少同步4次,科目主数据可以日终批处理。
坑5:同义不同码——一个实体在多个系统有多个编码
现象:一个客户在CRM里编码是CRMC001234,在ERP里编码是10000034。订单导出的客户编码无法和CRM的客户报表对上,销售总监要的"客户全生命周期视图"做不出来。
原因:没有建立跨系统的客户主数据统一视图,也没有编码映射表。很多集团ERP和CRM各自维护客户,靠实施时人工对应,后面新增客户就漏了。
解决:在关系矩阵之外再建一张"编码映射表"(ENTITY_TYPE, ERP_CODE, CRM_CODE, MAP_STATUS)。业务数据表引用哪个系统的编码,就通过映射表转换。注意映射关系本身也是治理对象,必须记录建立时间、有效期间、负责人。这个问题延伸到医疗数据领域也一样:医疗本体和主数据区别在于本体是概念模型、主数据是可被业务系统引用的实例数据,但"同义不同码"的病历诊断编码、手术编码映射在所有行业都是同一个坑。
排查时不要只盯着数据本身。现象只是表象,先查"数据在哪一层断的":是源系统就没这个编码,还是同步丢了,还是转换规则写错。按这个顺序查,比瞎猜快得多。
6. 进阶:把关系结果做成数据血缘检查,防止"豪华版PPT"变成一次性交付
关系图和矩阵做完,如果不变成自动检查规则,三个月后再看就是废纸一张。我最常做的落地动作,是把每一对关系写成一个校验视图,挂进数据库定时任务。
下面是一个综合校验视图的例子,一次检查三类问题:孤儿引用、状态穿越、有效期失效。基于第2章的建表演示。
CREATE OR REPLACE VIEW v_check_order_master AS SELECT o.order_id, o.order_date, o.customer_code, c.customer_name, CASE WHEN c.customer_code IS NULL THEN '孤儿引用' WHEN o.order_date < c.valid_from THEN '引用未来主数据' WHEN o.order_date > c.valid_to THEN '引用失效主数据' ELSE '正常' END AS check_result FROM o2c_sales_order o LEFT JOIN mdm_customer c ON o.customer_code = c.customer_code WHERE c.customer_code IS NULL OR o.order_date < c.valid_from OR o.order_date > c.valid_to;逻辑说明:LEFT JOIN保证订单全部保留,WHERE条件筛出三类异常。check_result用CASE给出可读的异常类型,方便后续在告警平台里按类型分组统计。这个视图可以每天跑一次,把结果写入一张datas_quality_check_log表,保留30天,做趋势分析。
这样做的价值是:你的17页PPT交付后,不是躺在硬盘里,而是转化成了一组可执行的校验规则。后面再遇到"某个客户编码在订单里查不到",直接跑这个视图,五分钟定位是主数据删除、同步延迟还是单据录入错误。
我做第一个ERP主数据治理项目时,就是画完图、写完矩阵就交付了,结果下个月财务对账翻车,连夜查了三个小时发现是同步接口挂了。从那以后,我要求每张关系图必须有对应的SQL校验,没有校验的关系图不允许放进交付文档。这个习惯救了我很多次,希望帮到你。
本文还有配套的精品资源,点击获取