283 lines
9.8 KiB
SQL
283 lines
9.8 KiB
SQL
-- ============================================================================
|
|
-- Evaluation Points Tenant Cleanup Precheck
|
|
-- 目标:
|
|
-- 1. 在执行 schema_evaluation_points_tenant_cleanup.sql 前先识别风险
|
|
-- 2. 输出 area 分布、无法映射记录、共享域残留、编码重复情况
|
|
-- 3. 供 DBA / 开发在评审和落库前人工确认
|
|
-- 说明:
|
|
-- - 本脚本只读,不修改任何数据
|
|
-- - 建议在生产、预发、测试库分别执行并保存结果
|
|
-- ============================================================================
|
|
|
|
-- --------------------------------------------------------------------------
|
|
-- 0. 当前表结构确认
|
|
-- --------------------------------------------------------------------------
|
|
SELECT
|
|
column_name,
|
|
data_type,
|
|
is_nullable
|
|
FROM information_schema.columns
|
|
WHERE table_schema = 'public'
|
|
AND table_name = 'evaluation_points'
|
|
ORDER BY ordinal_position;
|
|
|
|
-- --------------------------------------------------------------------------
|
|
-- 1. 基础体量
|
|
-- --------------------------------------------------------------------------
|
|
SELECT COUNT(*) AS total_points
|
|
FROM public.evaluation_points;
|
|
|
|
-- --------------------------------------------------------------------------
|
|
-- 1.1 构建兼容旧库的预检视图
|
|
-- - 若旧库还没有 tenant_code / tenant_name,则自动补 NULL 占位
|
|
-- - 后续所有预检统一只读这个临时视图
|
|
-- --------------------------------------------------------------------------
|
|
DO $$
|
|
DECLARE
|
|
has_tenant_code BOOLEAN;
|
|
has_tenant_name BOOLEAN;
|
|
tenant_code_expr TEXT;
|
|
tenant_name_expr TEXT;
|
|
BEGIN
|
|
SELECT EXISTS (
|
|
SELECT 1
|
|
FROM information_schema.columns
|
|
WHERE table_schema = 'public'
|
|
AND table_name = 'evaluation_points'
|
|
AND column_name = 'tenant_code'
|
|
) INTO has_tenant_code;
|
|
|
|
SELECT EXISTS (
|
|
SELECT 1
|
|
FROM information_schema.columns
|
|
WHERE table_schema = 'public'
|
|
AND table_name = 'evaluation_points'
|
|
AND column_name = 'tenant_name'
|
|
) INTO has_tenant_name;
|
|
|
|
tenant_code_expr := CASE
|
|
WHEN has_tenant_code THEN 'tenant_code'
|
|
ELSE 'NULL::VARCHAR(64) AS tenant_code'
|
|
END;
|
|
|
|
tenant_name_expr := CASE
|
|
WHEN has_tenant_name THEN 'tenant_name'
|
|
ELSE 'NULL::VARCHAR(128) AS tenant_name'
|
|
END;
|
|
|
|
EXECUTE format(
|
|
'CREATE TEMP VIEW tmp_evaluation_points_precheck AS
|
|
SELECT
|
|
id,
|
|
code,
|
|
name,
|
|
area,
|
|
%s,
|
|
%s
|
|
FROM public.evaluation_points',
|
|
tenant_code_expr,
|
|
tenant_name_expr
|
|
);
|
|
END $$;
|
|
|
|
SELECT
|
|
COUNT(*) AS total_points,
|
|
COUNT(*) FILTER (WHERE tenant_code IS NULL OR BTRIM(tenant_code) = '') AS missing_tenant_code,
|
|
COUNT(*) FILTER (WHERE tenant_name IS NULL OR BTRIM(tenant_name) = '') AS missing_tenant_name,
|
|
COUNT(*) FILTER (WHERE area IS NULL OR BTRIM(area) = '') AS blank_area
|
|
FROM tmp_evaluation_points_precheck;
|
|
|
|
-- --------------------------------------------------------------------------
|
|
-- 2. area 值分布
|
|
-- --------------------------------------------------------------------------
|
|
SELECT
|
|
COALESCE(NULLIF(BTRIM(area), ''), '<EMPTY>') AS area_value,
|
|
COUNT(*) AS point_count
|
|
FROM tmp_evaluation_points_precheck
|
|
GROUP BY 1
|
|
ORDER BY point_count DESC, area_value ASC;
|
|
|
|
-- --------------------------------------------------------------------------
|
|
-- 3. area 无法映射租户编码的残留清单
|
|
-- 规则:别名表 -> 租户名 -> 共享域兼容值
|
|
-- --------------------------------------------------------------------------
|
|
WITH alias_map AS (
|
|
SELECT DISTINCT ON (LOWER(BTRIM(alias_value)))
|
|
LOWER(BTRIM(alias_value)) AS normalized_alias_value,
|
|
tenant_code
|
|
FROM public.sys_tenant_aliases
|
|
WHERE deleted_at IS NULL
|
|
AND is_enabled = TRUE
|
|
ORDER BY LOWER(BTRIM(alias_value)), id ASC
|
|
),
|
|
tenant_name_map AS (
|
|
SELECT
|
|
LOWER(BTRIM(tenant_name)) AS normalized_tenant_name,
|
|
tenant_code
|
|
FROM public.sys_tenants
|
|
WHERE deleted_at IS NULL
|
|
AND is_enabled = TRUE
|
|
),
|
|
resolved_points AS (
|
|
SELECT
|
|
ep.id,
|
|
ep.code,
|
|
ep.name,
|
|
ep.area,
|
|
COALESCE(
|
|
NULLIF(BTRIM(ep.tenant_code), ''),
|
|
am.tenant_code,
|
|
tn.tenant_code,
|
|
CASE
|
|
WHEN ep.area IS NULL OR BTRIM(ep.area) = '' THEN 'PUBLIC'
|
|
WHEN LOWER(BTRIM(ep.area)) = 'default' THEN 'PUBLIC'
|
|
WHEN BTRIM(ep.area) = '公共' THEN 'PUBLIC'
|
|
WHEN BTRIM(ep.area) IN ('省级', '省局') THEN 'PROVINCIAL'
|
|
ELSE NULL
|
|
END
|
|
) AS resolved_tenant_code
|
|
FROM tmp_evaluation_points_precheck ep
|
|
LEFT JOIN alias_map am
|
|
ON LOWER(BTRIM(COALESCE(ep.area, ''))) = am.normalized_alias_value
|
|
LEFT JOIN tenant_name_map tn
|
|
ON LOWER(BTRIM(COALESCE(ep.area, ''))) = tn.normalized_tenant_name
|
|
)
|
|
SELECT
|
|
id,
|
|
code,
|
|
name,
|
|
area
|
|
FROM resolved_points
|
|
WHERE resolved_tenant_code IS NULL
|
|
ORDER BY id ASC;
|
|
|
|
-- --------------------------------------------------------------------------
|
|
-- 4. 共享域残留统计
|
|
-- --------------------------------------------------------------------------
|
|
SELECT
|
|
CASE
|
|
WHEN area IS NULL OR BTRIM(area) = '' THEN '<EMPTY>'
|
|
ELSE BTRIM(area)
|
|
END AS shared_area_value,
|
|
COUNT(*) AS point_count
|
|
FROM tmp_evaluation_points_precheck
|
|
WHERE area IS NULL
|
|
OR BTRIM(area) = ''
|
|
OR LOWER(BTRIM(area)) = 'default'
|
|
OR BTRIM(area) IN ('公共', '省级', '省局')
|
|
GROUP BY 1
|
|
ORDER BY point_count DESC, shared_area_value ASC;
|
|
|
|
-- --------------------------------------------------------------------------
|
|
-- 5. tenant_name 映射冲突预检
|
|
-- --------------------------------------------------------------------------
|
|
SELECT
|
|
LOWER(BTRIM(tenant_name)) AS normalized_tenant_name,
|
|
COUNT(DISTINCT tenant_code) AS tenant_code_count,
|
|
ARRAY_AGG(DISTINCT tenant_code ORDER BY tenant_code) AS tenant_codes
|
|
FROM public.sys_tenants
|
|
WHERE deleted_at IS NULL
|
|
AND is_enabled = TRUE
|
|
AND tenant_name IS NOT NULL
|
|
AND BTRIM(tenant_name) <> ''
|
|
GROUP BY 1
|
|
HAVING COUNT(DISTINCT tenant_code) > 1
|
|
ORDER BY normalized_tenant_name ASC;
|
|
|
|
-- --------------------------------------------------------------------------
|
|
-- 6. alias 映射冲突预检
|
|
-- --------------------------------------------------------------------------
|
|
SELECT
|
|
LOWER(BTRIM(alias_value)) AS normalized_alias_value,
|
|
COUNT(DISTINCT tenant_code) AS tenant_code_count,
|
|
ARRAY_AGG(DISTINCT tenant_code ORDER BY tenant_code) AS tenant_codes
|
|
FROM public.sys_tenant_aliases
|
|
WHERE deleted_at IS NULL
|
|
AND is_enabled = TRUE
|
|
AND alias_value IS NOT NULL
|
|
AND BTRIM(alias_value) <> ''
|
|
GROUP BY 1
|
|
HAVING COUNT(DISTINCT tenant_code) > 1
|
|
ORDER BY normalized_alias_value ASC;
|
|
|
|
-- --------------------------------------------------------------------------
|
|
-- 7. 编码唯一性现状预检
|
|
-- 注意:当前 service 仍按全局唯一校验 code,不是按 tenant_code + code 校验
|
|
-- --------------------------------------------------------------------------
|
|
SELECT
|
|
LOWER(BTRIM(code)) AS normalized_code,
|
|
COUNT(*) AS duplicate_count,
|
|
ARRAY_AGG(id ORDER BY id) AS point_ids
|
|
FROM tmp_evaluation_points_precheck
|
|
WHERE code IS NOT NULL
|
|
AND BTRIM(code) <> ''
|
|
GROUP BY 1
|
|
HAVING COUNT(*) > 1
|
|
ORDER BY duplicate_count DESC, normalized_code ASC;
|
|
|
|
-- --------------------------------------------------------------------------
|
|
-- 8. 若后续想把 code 改成“按租户唯一”,先看跨租户重复情况
|
|
-- 这里用“预估 tenant_code”做模拟,不代表当前表已有 tenant_code
|
|
-- --------------------------------------------------------------------------
|
|
WITH alias_map AS (
|
|
SELECT DISTINCT ON (LOWER(BTRIM(alias_value)))
|
|
LOWER(BTRIM(alias_value)) AS normalized_alias_value,
|
|
tenant_code
|
|
FROM public.sys_tenant_aliases
|
|
WHERE deleted_at IS NULL
|
|
AND is_enabled = TRUE
|
|
ORDER BY LOWER(BTRIM(alias_value)), id ASC
|
|
),
|
|
tenant_name_map AS (
|
|
SELECT
|
|
LOWER(BTRIM(tenant_name)) AS normalized_tenant_name,
|
|
tenant_code
|
|
FROM public.sys_tenants
|
|
WHERE deleted_at IS NULL
|
|
AND is_enabled = TRUE
|
|
),
|
|
resolved_points AS (
|
|
SELECT
|
|
ep.id,
|
|
LOWER(BTRIM(ep.code)) AS normalized_code,
|
|
COALESCE(
|
|
NULLIF(BTRIM(ep.tenant_code), ''),
|
|
am.tenant_code,
|
|
tn.tenant_code,
|
|
CASE
|
|
WHEN ep.area IS NULL OR BTRIM(ep.area) = '' THEN 'PUBLIC'
|
|
WHEN LOWER(BTRIM(ep.area)) = 'default' THEN 'PUBLIC'
|
|
WHEN BTRIM(ep.area) = '公共' THEN 'PUBLIC'
|
|
WHEN BTRIM(ep.area) IN ('省级', '省局') THEN 'PROVINCIAL'
|
|
ELSE NULL
|
|
END
|
|
) AS resolved_tenant_code
|
|
FROM tmp_evaluation_points_precheck ep
|
|
LEFT JOIN alias_map am
|
|
ON LOWER(BTRIM(COALESCE(ep.area, ''))) = am.normalized_alias_value
|
|
LEFT JOIN tenant_name_map tn
|
|
ON LOWER(BTRIM(COALESCE(ep.area, ''))) = tn.normalized_tenant_name
|
|
WHERE ep.code IS NOT NULL
|
|
AND BTRIM(ep.code) <> ''
|
|
)
|
|
SELECT
|
|
normalized_code,
|
|
COUNT(*) AS duplicate_count,
|
|
COUNT(DISTINCT resolved_tenant_code) AS tenant_count,
|
|
ARRAY_AGG(
|
|
CONCAT(id, ':', COALESCE(resolved_tenant_code, '<UNRESOLVED>'))
|
|
ORDER BY id
|
|
) AS point_ids_with_tenant
|
|
FROM resolved_points
|
|
GROUP BY normalized_code
|
|
HAVING COUNT(*) > 1
|
|
ORDER BY duplicate_count DESC, normalized_code ASC;
|
|
|
|
-- --------------------------------------------------------------------------
|
|
-- 9. 执行后验收时建议对照的基线统计
|
|
-- --------------------------------------------------------------------------
|
|
SELECT
|
|
COUNT(*) FILTER (WHERE tenant_code IS NULL OR BTRIM(tenant_code) = '') AS missing_tenant_code,
|
|
COUNT(*) FILTER (WHERE tenant_name IS NULL OR BTRIM(tenant_name) = '') AS missing_tenant_name
|
|
FROM tmp_evaluation_points_precheck;
|