# `Sp_System_CheckMaterialsInvalid` (procedure) > 材料作废校验 - **Type:** PROCEDURE - **Deterministic:** NO - **SQL data access:** CONTAINS SQL ## Parameters | # | Mode | Name | Type | |---|---|---|---| | 1 | IN | `sFormGuid` | `varchar(100)` | | 2 | IN | `sGuid` | `varchar(100)` | | 3 | IN | `sTableName` | `varchar(100)` | | 4 | IN | `sLoginId` | `varchar(100)` | | 5 | OUT | `sReturn` | `varchar(4000)` | | 6 | IN | `sBrId` | `varchar(100)` | | 7 | IN | `sSuId` | `varchar(100)` | | 8 | OUT | `sCode` | `int` | ## Body _Body is not pre-cached. To inspect: `mysql --defaults-file=~/.my.cnf -e 'SHOW CREATE PROCEDURE `Sp_System_CheckMaterialsInvalid`'`._ ## Narrative **Business context:** 材料作废校验 — blocks save of a 工单 / 报价单 when any referenced material has been retired (`elematerials.bInvalid=1`) and additionally blocks 工单 save when its upstream 销售订单 has been unaudited/deleted. Used by the standard post-save validator hook to keep retired-material work-orders out of production. **What it does:** On `sTableName='mftworkordermaster'` joins `mftworkordermaterials` to `elematerials` and collects `GROUP_CONCAT(sMaterialsName)` where `bInvalid=1`; on `quoquotationmaster` does the same against `quoquotationmaterials`. If any names come back, returns `sCode=-8` with `':材料已作废,不能保存'`. Then counts `salsalesordermaster` rows referenced by `mftworkorderslave.sSrcId` whose `bCheck=1`; zero means the source order has been retracted or deleted, so it returns `sCode=-1` with `'订单已消审/或已删除 不能保存工单数据 请核查订单数据'`. **Invocation:** Standard `gdsmodule.sSaveProName` post-save validator, dispatched by `BusinessBaseServiceImpl.checkUpdate(..., "sSaveProName")` (which delegates to `checkSaveService.getCheckSaveUpd`). The install script `script/标版/30100101/Sp_System_CheckMaterialsInvalid.sql` is the only deployed copy; no current `gdsmodule.sSaveProName` row in this DB instance binds it, so it ships as a customer-configurable check. The `L` variant drops the salsalesorder check.