-- ============================================================================ -- 授权码字符串整体移除:设备码 = MAC -- -- 背景:一台设备原先有两个标识——20 字符的 license 串(分表主键 code)与 MAC -- (devicemac 列),指向同一台设备。而绑定、禁用、重置、结算反查批次**全都只用 MAC**, -- license 从头到尾没有任何一处校验。MAC 的前 2 字节就是 PID,产品/批次/渠道都能从它 -- 查回来,所以第二套标识没有存在价值,反而让「设备的唯一标识到底是哪个」长期说不清。 -- -- 代码侧已做的事(见 apps/services): -- * 删除 utils/license 包;生成侧一律 code = devicemac、codetype = DEVICECODE(1) -- * utils/devcode 只解析 MAC,解不出直接报错(不再回退到写死的 PID) -- * 不再创建裸的 license 表;删产品时连带删掉它的 license_ 分表 -- -- ⚠️ **正常情况下不需要手工执行这份 SQL**:console 启动时的 -- migrateLicenseCodeToMac(modules/console/registry.go)会幂等地做完全部三步。 -- 这里留一份等价 SQL 供离线核对 / 应急使用。 -- -- 幂等:可重复执行。 -- ============================================================================ \set ON_ERROR_STOP on BEGIN; -- ① 存量 code 改写成该行的 MAC。 -- 跑过一遍之后是 0 行更新。devicemac 为空的行不动(没有 MAC 就没得改, -- 这类行只可能来自更早的、连 MAC 都没生成的产品,需要人工确认后再处理)。 DO $do$ DECLARE t text; n bigint; BEGIN FOR t IN SELECT tablename FROM pg_tables WHERE schemaname = current_schema() AND tablename LIKE 'license\_%' LOOP EXECUTE format('UPDATE %I SET code = devicemac WHERE devicemac <> '''' AND code <> devicemac', t); GET DIAGNOSTICS n = ROW_COUNT; IF n > 0 THEN RAISE NOTICE '% : % 条 code 已改写成 MAC', t, n; END IF; END LOOP; END $do$; -- ② 删掉「没有对应产品且为空」的 license_* 孤儿分表,以及裸的 license 表。 -- 建表按产品列表做、删产品却只删产品行,于是删一个产品留一张空表 -- (2026-09-02 的 along 环境上已攒了 44 张)。 -- -- ⚠️ 只删空表:有数据说明判断依据错了(产品被误删、或表名规则变过), -- 这种时候宁可留着一张查得到的表,也不要把已经发出去的设备记录抹掉。 DO $do$ DECLARE t text; n bigint; BEGIN FOR t IN SELECT tablename FROM pg_tables WHERE schemaname = current_schema() AND (tablename = 'license' OR tablename LIKE 'license\_%') LOOP -- 裸 license 表没有对应产品,恒进入清理判定 IF t <> 'license' AND EXISTS ( SELECT 1 FROM product p WHERE lower(to_hex(p.id)) = substring(t from 9) ) THEN CONTINUE; END IF; EXECUTE format('SELECT count(*) FROM %I', t) INTO n; IF n > 0 THEN RAISE WARNING '% 没有对应产品但有 % 行数据,已跳过', t, n; CONTINUE; END IF; EXECUTE format('DROP TABLE IF EXISTS %I', t); RAISE NOTICE '已清理空的孤儿表 %', t; END LOOP; END $do$; COMMIT; -- ============================================================================ -- 体检 SQL(迁移后手工执行) -- -- 1) 应当没有任何 code 与 devicemac 不一致的行: -- DO $$ DECLARE t text; n bigint; BEGIN -- FOR t IN SELECT tablename FROM pg_tables WHERE tablename LIKE 'license\_%' LOOP -- EXECUTE format('SELECT count(*) FROM %I WHERE code <> devicemac', t) INTO n; -- IF n > 0 THEN RAISE WARNING '% 还有 % 行不一致', t, n; END IF; -- END LOOP; -- END $$; -- -- 2) 剩下的 license_* 应当与 product 一一对应: -- SELECT t.tablename, -- EXISTS(SELECT 1 FROM product p WHERE lower(to_hex(p.id)) = substring(t.tablename from 9)) AS 有产品 -- FROM pg_tables t WHERE t.tablename LIKE 'license\_%'; -- ============================================================================