Просмотр исходного кода

fix(sql): avoid MySQL 1093 on production pre-transit role grants.

Co-authored-by: Cursor <cursoragent@cursor.com>
zlwu 2 месяцев назад
Родитель
Сommit
3a6e2ca128
1 измененных файлов с 44 добавлено и 40 удалено
  1. 44 40
      docs/sql/alter_sys_menu_add_production_pre_transit_sample.sql

+ 44 - 40
docs/sql/alter_sys_menu_add_production_pre_transit_sample.sql

@@ -86,30 +86,32 @@ SET
 WHERE id COLLATE utf8mb4_unicode_ci = @menu_f;
 
 -- 3) 目标角色:已有 PRM 下任一有效子菜单授权
+-- MySQL 5.7:UPDATE 目标表不可在同句 FROM/EXISTS 中直接引用自身,须用派生表
+
 -- 3a) 恢复软删的 PRM / C / F 授权
 UPDATE sys_role_menu rm
 INNER JOIN sys_role r
   ON r.id COLLATE utf8mb4_unicode_ci = rm.role_id COLLATE utf8mb4_unicode_ci
  AND r.del_flag = 0
  AND r.tenant_no COLLATE utf8mb4_unicode_ci = @tenant_no
+INNER JOIN (
+  SELECT DISTINCT rm2.role_id AS role_id
+  FROM sys_role_menu rm2
+  INNER JOIN sys_menu m2
+    ON m2.id COLLATE utf8mb4_unicode_ci = rm2.menu_id COLLATE utf8mb4_unicode_ci
+   AND m2.del_flag = 0
+   AND m2.parent_id COLLATE utf8mb4_unicode_ci = @prm_id
+  WHERE rm2.tenant_no COLLATE utf8mb4_unicode_ci = @tenant_no
+    AND rm2.del_flag = 0
+) eligible
+  ON eligible.role_id COLLATE utf8mb4_unicode_ci = r.id COLLATE utf8mb4_unicode_ci
 SET
   rm.del_flag = 0,
   rm.update_time = NOW(),
   rm.remark = 'grant production pre-transit to PRM roles'
 WHERE rm.tenant_no COLLATE utf8mb4_unicode_ci = @tenant_no
   AND rm.del_flag = 1
-  AND rm.menu_id COLLATE utf8mb4_unicode_ci IN (@prm_id, @menu_c, @menu_f)
-  AND EXISTS (
-    SELECT 1
-    FROM sys_role_menu rm2
-    INNER JOIN sys_menu m2
-      ON m2.id COLLATE utf8mb4_unicode_ci = rm2.menu_id COLLATE utf8mb4_unicode_ci
-     AND m2.del_flag = 0
-     AND m2.parent_id COLLATE utf8mb4_unicode_ci = @prm_id
-    WHERE rm2.role_id COLLATE utf8mb4_unicode_ci = r.id COLLATE utf8mb4_unicode_ci
-      AND rm2.tenant_no COLLATE utf8mb4_unicode_ci = @tenant_no
-      AND rm2.del_flag = 0
-  );
+  AND rm.menu_id COLLATE utf8mb4_unicode_ci IN (@prm_id, @menu_c, @menu_f);
 
 -- 3b) 插入缺失授权(PRM + C + F)
 INSERT INTO sys_role_menu (
@@ -117,9 +119,9 @@ INSERT INTO sys_role_menu (
   create_by, create_dept_id, create_time, update_by, update_time, del_flag
 )
 SELECT
-  UPPER(MD5(CONCAT(r.id, '|', x.menu_id))),
-  r.id,
-  x.menu_id,
+  UPPER(MD5(CONCAT(src.role_id, '|', src.menu_id))),
+  src.role_id,
+  src.menu_id,
   @tenant_no,
   0,
   'grant production pre-transit to PRM roles',
@@ -129,34 +131,36 @@ SELECT
   NULL,
   NOW(),
   0
-FROM sys_role r
-INNER JOIN (
-  SELECT @prm_id AS menu_id
-  UNION ALL SELECT @menu_c
-  UNION ALL SELECT @menu_f
-) x
-WHERE r.del_flag = 0
-  AND r.tenant_no COLLATE utf8mb4_unicode_ci = @tenant_no
-  AND EXISTS (
-    SELECT 1
+FROM (
+  SELECT
+    r.id AS role_id,
+    x.menu_id AS menu_id
+  FROM sys_role r
+  INNER JOIN (
+    SELECT @prm_id AS menu_id
+    UNION ALL SELECT @menu_c
+    UNION ALL SELECT @menu_f
+  ) x
+  INNER JOIN (
+    SELECT DISTINCT rm2.role_id AS role_id
     FROM sys_role_menu rm2
     INNER JOIN sys_menu m2
       ON m2.id COLLATE utf8mb4_unicode_ci = rm2.menu_id COLLATE utf8mb4_unicode_ci
      AND m2.del_flag = 0
      AND m2.parent_id COLLATE utf8mb4_unicode_ci = @prm_id
-    WHERE rm2.role_id COLLATE utf8mb4_unicode_ci = r.id COLLATE utf8mb4_unicode_ci
-      AND rm2.tenant_no COLLATE utf8mb4_unicode_ci = @tenant_no
+    WHERE rm2.tenant_no COLLATE utf8mb4_unicode_ci = @tenant_no
       AND rm2.del_flag = 0
-  )
-  AND EXISTS (
-    SELECT 1 FROM sys_menu m
-    WHERE m.id COLLATE utf8mb4_unicode_ci = x.menu_id
-      AND m.del_flag = 0
-  )
-  AND NOT EXISTS (
-    SELECT 1 FROM sys_role_menu rm
-    WHERE rm.role_id COLLATE utf8mb4_unicode_ci = r.id COLLATE utf8mb4_unicode_ci
-      AND rm.menu_id COLLATE utf8mb4_unicode_ci = x.menu_id
-      AND rm.tenant_no COLLATE utf8mb4_unicode_ci = @tenant_no
-      AND rm.del_flag = 0
-  );
+  ) eligible
+    ON eligible.role_id COLLATE utf8mb4_unicode_ci = r.id COLLATE utf8mb4_unicode_ci
+  INNER JOIN sys_menu m
+    ON m.id COLLATE utf8mb4_unicode_ci = x.menu_id
+   AND m.del_flag = 0
+  WHERE r.del_flag = 0
+    AND r.tenant_no COLLATE utf8mb4_unicode_ci = @tenant_no
+) src
+LEFT JOIN sys_role_menu existing
+  ON existing.role_id COLLATE utf8mb4_unicode_ci = src.role_id COLLATE utf8mb4_unicode_ci
+ AND existing.menu_id COLLATE utf8mb4_unicode_ci = src.menu_id COLLATE utf8mb4_unicode_ci
+ AND existing.tenant_no COLLATE utf8mb4_unicode_ci = @tenant_no
+ AND existing.del_flag = 0
+WHERE existing.id IS NULL;