无需手动逐列映射 如何基于id从A_STG表更新目标表A的对应记录
解决方案
核心思路是通过数据库的元数据表自动拼接动态更新语句,不需要手动罗列所有字段,适配不同数据库的实现方法如下:
1 MySQL 实现
首先执行以下SQL生成所需的更新语句:
SELECT CONCAT( 'UPDATE A t1 JOIN A_STG t2 ON t1.id = t2.id SET ', GROUP_CONCAT(CONCAT('t1.', COLUMN_NAME, ' = t2.', COLUMN_NAME)), ';' ) AS update_sql FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'A' AND TABLE_SCHEMA = DATABASE(); -- 此处替换为实际数据库名
执行后会输出完整的UPDATE语句,复制出来直接运行即可完成更新。
如果需要一步到位直接执行,可使用动态SQL:
SET @sql = ( SELECT CONCAT( 'UPDATE A t1 JOIN A_STG t2 ON t1.id = t2.id SET ', GROUP_CONCAT(CONCAT('t1.', COLUMN_NAME, ' = t2.', COLUMN_NAME)) ) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'A' AND TABLE_SCHEMA = DATABASE() ); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
2 PostgreSQL 实现
生成更新语句的SQL如下:
SELECT 'UPDATE A t1 SET ' || string_agg(quote_ident(column_name) || ' = t2.' || quote_ident(column_name), ', ') || ' FROM A_STG t2 WHERE t1.id = t2.id;' AS update_sql FROM information_schema.columns WHERE table_name = 'a' AND table_schema = current_schema();
拿到生成的语句后执行即可,也可以用DO块直接执行动态SQL:
DO $$ DECLARE v_sql text; BEGIN SELECT 'UPDATE A t1 SET ' || string_agg(quote_ident(column_name) || ' = t2.' || quote_ident(column_name), ', ') || ' FROM A_STG t2 WHERE t1.id = t2.id' INTO v_sql FROM information_schema.columns WHERE table_name = 'a' AND table_schema = current_schema(); EXECUTE v_sql; END $$;
3 Oracle 实现
生成更新语句的SQL:
SELECT 'UPDATE A t1 SET ' || LISTAGG('t1.' || COLUMN_NAME || ' = t2.' || COLUMN_NAME, ', ') || ' WHERE EXISTS (SELECT 1 FROM A_STG t2 WHERE t1.id = t2.id);' AS update_sql FROM ALL_TAB_COLUMNS WHERE TABLE_NAME = 'A' AND OWNER = '你的数据库用户名';
直接执行生成的语句即可,也可以用PL/SQL执行动态语句。
注意:执行更新前建议先备份表A的数据,或者先把生成的UPDATE语句改成SELECT语句验证关联逻辑是否正确,避免误更新数据。
内容的提问来源于stack exchange,提问作者Mr.Rendezvous
相关产品推荐
相关产品推荐

