/* ============================================================================ 删除策略重构:s_relation 删除处置三值 + 新建删除 SQL 规则表 s_delete_rule ---------------------------------------------------------------------------- 依据:FMS删除策略重构设计.md v1.2 第一阶段元数据脚本,只改结构,不含初始化数据。 本脚本可重复执行: - s_relation.b_on_delete 不存在时才加,且默认值取 'restrict'; - 存量关系的 b_on_delete 不批量回填(设计 §3.1:避免上线后突然改变存量删除行为); 仅把历史遗留的 'archive' 归一到 'none'(阶段一不支持归档,避免执行器遇到未知值); - s_delete_rule 不存在才建;旧的 s_rule 已废弃,按需手工 drop(见文件末尾说明)。 执行:fms-api 目录下 java -cp "tools/migration/mssql-jdbc-13.4.0.jre11.jar" tools/migration/RunSqlFile.java \ ../sql/fms_delete_rule.sql --dry-run 确认分批正确后去掉 --dry-run 实跑(按 GO 分批、单事务、失败整体回滚)。 ============================================================================ */ /* 1. b_on_delete:补列并设定新语义的默认值。 新值域 restrict / cascade / none;默认 restrict 只作用于新建行, 存量行保持原值(历史为 'none'),由单独迁移决定是否升级。 */ if col_length('dbo.s_relation', 'b_on_delete') is null begin alter table dbo.s_relation add b_on_delete varchar(20) not null constraint df_s_relation_on_delete default 'restrict'; end GO /* 2. 列已存在时,只改默认值约束,不动存量数据。 */ if col_length('dbo.s_relation', 'b_on_delete') is not null begin declare @constraint sysname; select @constraint = dc.name from sys.default_constraints dc join sys.columns c on c.object_id = dc.parent_object_id and c.column_id = dc.parent_column_id where dc.parent_object_id = object_id('dbo.s_relation') and c.name = 'b_on_delete'; if @constraint is not null begin declare @dropSql nvarchar(400) = N'alter table dbo.s_relation drop constraint ' + quotename(@constraint); exec sp_executesql @dropSql; end alter table dbo.s_relation add constraint df_s_relation_on_delete default 'restrict' for b_on_delete; end GO /* 3. 历史 'archive' 阶段一不支持:归一为 'none'(不处理、不保护), 避免删除执行器读到未知处置值。空值与非法值同样归一,保证值域收敛。 */ update dbo.s_relation set b_on_delete = 'none' where b_on_delete is null or b_on_delete not in ('restrict', 'cascade', 'none'); GO /* 4. 删除 SQL 规则表。 */ if object_id('dbo.s_delete_rule', 'U') is null begin create table dbo.s_delete_rule ( b_id bigint not null, -- 雪花主键(新增时前端经 /data/nextid 取号) b_module_id varchar(50) not null, -- 规则所属数据模块编码(对应 s_module.b_id) b_sql nvarchar(max) not null, -- 只读查询 SQL,用 :ids 标记本次待删 ID 集合 b_message nvarchar(500) null, -- 删除失败时的提示文案(第一阶段固定文案) b_canuse tinyint not null default 1, -- 是否启用(0/1) b_xh int not null default 0, -- 执行顺序(并列按 b_xh、b_id) b_created_by varchar(50) null, -- 审计列由服务端维护,配置界面不提交 b_created_at datetime2 null, b_updated_by varchar(50) null, b_updated_at datetime2 null, primary key (b_id) ); end GO if not exists ( select 1 from sys.indexes where name = 'ix_s_delete_rule_module' and object_id = object_id('dbo.s_delete_rule') ) begin create index ix_s_delete_rule_module on dbo.s_delete_rule (b_module_id, b_canuse, b_xh); end GO /* 5. 旧表 s_rule 的处置。 已确认库内 s_rule 无配置数据,可直接重建;此处刻意不 drop, 避免脚本误伤可能存在的历史配置。确认无数据后手工执行: drop table if exists dbo.s_rule; 若库中确实存在规则数据,需先迁移: - b_scope_type='module' 且 b_predicate 为 SQL 文本 → 写入 s_delete_rule (b_module_id = b_scope_id,b_sql = b_predicate); - b_scope_type='relation'(引用规则)→ 置该关系 s_relation.b_on_delete='restrict'; - b_predicate 为 JSON 勾条件的数据无法自动转换,需人工改写为等价 SQL。 */