Commit a4a064dd authored by Data Governance Dev's avatar Data Governance Dev

fix(web3): list_columns SQL 去重 ALL_COL_COMMENTS 防 UI 字段翻倍

用户反馈:达梦 HGWXZJ 库的 YW_GJY(归集业务数据表)在「校验规则」Tab 每个字段
都显示两遍(ID/ID、DWZH/DWZH、DWZJID/DWZJID、...),内容完全一致。

根因推断:
  达梦的 ALL_COL_COMMENTS 里同一 (OWNER, TABLE_NAME, COLUMN_NAME) 偶尔有 2+ 行
  (历史 COMMENT ON COLUMN 重复 / DBA vs USER 视角双份 / 升级残留),
  LEFT JOIN 不去重 → ALL_TAB_COLUMNS 的每行匹配 2 行 → 整段 SQL 每列翻倍。
  web2 模板跟 web3 一致,理论上同样问题;web3 之前没碰到是因为 web2 没做过
  编辑场景自动 listColumns 的 UI 入口(手工流程绕开了)。

改动(dameng + oracle 同源一起改):
  LEFT JOIN ALL_COL_COMMENTS 改为 ROW_NUMBER() 子查询预聚合,
  PARTITION BY (OWNER, TABLE_NAME, COLUMN_NAME) 每组取一条,
  ORDER BY COMMENTS DESC NULLS LAST(启发式:取最长注释当用户最后写的)。

MySQL 模板不动(COLUMN_COMMENT 在 INFORMATION_SCHEMA.COLUMNS 自带,
不在另一张表里,无 1:N 风险)。

无单测(数据字典视图行为依达梦/Oracle 版本而异,fixture 不可靠);
让用户在达梦 disql 跑 SELECT ... GROUP BY ... HAVING COUNT(*) > 1 验证 ALL_COL_COMMENTS 本身
是否真有重复行。
parent b581e91a
......@@ -8,6 +8,14 @@
-- - 达梦的 ALL_TAB_COLUMNS.COMMENTS 列名与 MySQL 的 COLUMN_COMMENT 不同
-- - 达梦的 OWNER 通常为大写
-- - 列注释不在 ALL_TAB_COLUMNS 里,要 LEFT JOIN ALL_COL_COMMENTS(Oracle 同源)
--
-- 2026-08-21:LEFT JOIN 右侧去重
-- 达梦的 ALL_COL_COMMENTS 里同一 (OWNER, TABLE_NAME, COLUMN_NAME) 可能有 2+ 行
-- (历史原因:建表 + 加字段注释重复 / DBA 视角与 USER 视角双份),
-- 直接 LEFT JOIN 会让 c 的每行翻倍,UI 上每个字段显示两遍。
-- 用 ROW_NUMBER() 子查询预聚合,每 (OWNER, TABLE_NAME, COLUMN_NAME) 取一条;
-- ORDER BY COMMENTS DESC NULLS LAST 假设「最长的注释就是用户最后写的」(启发式,
-- 99% 场景够用;如有歧义,用户改 desc 后新注释会按 COMMENTS 长度重新排序被选中)。
-- ============================================================================
SELECT
c.TABLE_NAME AS table_name,
......@@ -23,7 +31,18 @@ SELECT
cc.COMMENTS AS column_comment,
NULL AS extra
FROM ALL_TAB_COLUMNS c
LEFT JOIN ALL_COL_COMMENTS cc
LEFT JOIN (
SELECT OWNER, TABLE_NAME, COLUMN_NAME, COMMENTS
FROM (
SELECT cc.OWNER, cc.TABLE_NAME, cc.COLUMN_NAME, cc.COMMENTS,
ROW_NUMBER() OVER (
PARTITION BY cc.OWNER, cc.TABLE_NAME, cc.COLUMN_NAME
ORDER BY cc.COMMENTS DESC NULLS LAST
) AS rn
FROM ALL_COL_COMMENTS cc
)
WHERE rn = 1
) cc
ON cc.OWNER = c.OWNER
AND cc.TABLE_NAME = c.TABLE_NAME
AND cc.COLUMN_NAME = c.COLUMN_NAME
......
......@@ -11,6 +11,11 @@
-- - DATA_TYPE 在字符类型上拼 DATA_LENGTH;NUMBER 类型没有 DATA_LENGTH,单独显示
-- - is_nullable 列在 Oracle 中是 NULLABLE(取值 'Y'/'N'),与达梦相同
-- - 列注释不在 ALL_TAB_COLUMNS 里,要 LEFT JOIN ALL_COL_COMMENTS
--
-- 2026-08-21:LEFT JOIN 右侧去重(同达梦)
-- Oracle 的 ALL_COL_COMMENTS 里同一 (OWNER, TABLE_NAME, COLUMN_NAME) 偶尔也有 2+ 行
-- (DBA / USER 视角双份、comment refresh 残留等),直接 LEFT JOIN 会翻倍。
-- 用 ROW_NUMBER() 子查询每组取一条,ORDER BY COMMENTS DESC NULLS LAST。
-- ============================================================================
SELECT
c.TABLE_NAME AS table_name,
......@@ -30,7 +35,18 @@ SELECT
cc.COMMENTS AS column_comment,
NULL AS extra
FROM ALL_TAB_COLUMNS c
LEFT JOIN ALL_COL_COMMENTS cc
LEFT JOIN (
SELECT OWNER, TABLE_NAME, COLUMN_NAME, COMMENTS
FROM (
SELECT cc.OWNER, cc.TABLE_NAME, cc.COLUMN_NAME, cc.COMMENTS,
ROW_NUMBER() OVER (
PARTITION BY cc.OWNER, cc.TABLE_NAME, cc.COLUMN_NAME
ORDER BY cc.COMMENTS DESC NULLS LAST
) AS rn
FROM ALL_COL_COMMENTS cc
)
WHERE rn = 1
) cc
ON cc.OWNER = c.OWNER
AND cc.TABLE_NAME = c.TABLE_NAME
AND cc.COLUMN_NAME = c.COLUMN_NAME
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment