当前位置: 首页 > news >正文

【达梦数据库】存储过程统计模式下表信息-SQL改写

背景

在一次Oracle迁移Dm的过程中,源库&目的库大小写均敏感,执行客户提供的SQL脚本的过程中发现,表ip_address被系统默认成了表IP_ADDRESS
经过分析,客户提供的SQL没有使用双引号,来确保Oracle和Dm数据库按照指定的大小写来识别表名,因此,做以下改写。

源SQL

需要用目的用户去执行

declare num number;
beginselect count(1) into num from user_tables where table_name = 'TMP_GET_ACTURAL_TABLE_COUNT';if num > 0 thenexecute immediate 'drop table TMP_GET_ACTURAL_TABLE_COUNT';end if;
end;
/
create table TMP_GET_ACTURAL_TABLE_COUNT ( table_name varchar(50), table_cnt  int );/
CREATE OR REPLACE 
PROCEDURE "GET_ACTURAL_TABLE_COUNT"(isrun integer) AUTHID CURRENT_USER 
ISsqlstr varchar2(4000);
beginfor cursor_sql in ( select 'insert into TMP_GET_ACTURAL_TABLE_COUNT(table_name,table_cnt) select '''||table_name||''' as table_name,count(1) as table_cnt from '||table_name as sqlstr1 from user_tables where table_name not like 'SREF_CON_%') loopexecute immediate (cursor_sql.sqlstr1);commit;end loop;
end;
/
truncate table TMP_GET_ACTURAL_TABLE_COUNT;/
call GET_ACTURAL_TABLE_COUNT(1);
/
commit;
/select *from TMP_GET_ACTURAL_TABLE_COUNT order by upper(table_name);/

改写后SQL

需要用目的用户去执行

DECLAREnum NUMBER;
BEGINSELECT COUNT(1)INTOnumFROM user_tablesWHERE table_name = 'TMP_GET_ACTURAL_TABLE_COUNT';IF num > 0 THENEXECUTE IMMEDIATE 'DROP TABLE TMP_GET_ACTURAL_TABLE_COUNT';END IF;EXECUTE IMMEDIATE 'CREATE TABLE TMP_GET_ACTURAL_TABLE_COUNT(table_name VARCHAR2(50), table_cnt INT)';
END;
/
-- 创建存储过程
CREATE OR REPLACE
PROCEDURE "GET_ACTURAL_TABLE_COUNT"(isrun INTEGER) AUTHID CURRENT_USER
ISsqlstr VARCHAR2(4000);v_table_name USER_TABLES.TABLE_NAME%TYPE;
BEGIN-- 遍历所有用户表(排除以'SREF_CON_'开头的表)FOR rec IN (SELECT table_name FROM user_tables WHERE table_name NOT LIKE 'SREF_CON_%')LOOP-- 构建并执行SQL语句sqlstr := 'INSERT INTO TMP_GET_ACTURAL_TABLE_COUNT(table_name, table_cnt) SELECT ''' || rec.table_name || ''' AS table_name, COUNT(1) AS table_cnt FROM "' || rec.table_name || '"';EXECUTE IMMEDIATE sqlstr;END LOOP;-- 提交事务(在循环外提交)COMMIT;
END;
/
-- 调用存储过程
--BEGIN
--    GET_ACTURAL_TABLE_COUNT(1);
--END;
--/
-- 截断临时表(如果需要重新填充)
TRUNCATE TABLE TMP_GET_ACTURAL_TABLE_COUNT;/
-- 调用存储过程(如果需要)
BEGINGET_ACTURAL_TABLE_COUNT(1);
END;
/
-- 查询临时表SELECT * FROM TMP_GET_ACTURAL_TABLE_COUNT 
ORDER BY UPPER(table_name);/

通用SQL-(暂时未成功)

思路:使用DBA用户可以执行任何模式下的表信息的统计

-- 删除并重新创建临时表
DECLARE  num NUMBER;  target_schema VARCHAR2(50) := 'ECOLOGY_TARGET';  --填写目标模式,保证大小写正确
BEGIN  SELECT COUNT(1)   INTO num   FROM dba_tables   WHERE table_name = 'TMP_GET_ACTURAL_TABLE_COUNT'  AND owner = target_schema;  IF num > 0 THEN  EXECUTE IMMEDIATE 'DROP TABLE ' || target_schema || '.TMP_GET_ACTURAL_TABLE_COUNT';  END IF;  EXECUTE IMMEDIATE 'CREATE TABLE ' || target_schema || '.TMP_GET_ACTURAL_TABLE_COUNT(table_name VARCHAR2(50), table_cnt INT)';  
END;  
/CREATE OR REPLACE PROCEDURE GET_ACTURAL_TABLE_COUNT(isrun INTEGER) 
IS  sqlstr VARCHAR2(4000);  v_table_name USER_TABLES.TABLE_NAME%TYPE;  target_schema VARCHAR2(50) := 'ECOLOGY_TARGET';  --填写目标模式,保证大小写正确
BEGIN  -- 遍历用户表(排除以'SREF_CON_'开头的表)  FOR rec IN (SELECT table_name FROM dba_tables WHERE owner = 'target_schema' AND table_name NOT LIKE 'SREF_CON_%')   LOOP  -- 构建并执行SQL语句  sqlstr := 'INSERT INTO ' || target_schema || '.TMP_GET_ACTURAL_TABLE_COUNT(table_name, table_cnt) SELECT "' || rec.table_name || '" AS table_name, COUNT(1) AS table_cnt FROM "' || rec.table_name || '"';  EXECUTE IMMEDIATE sqlstr;  END LOOP;  -- 提交事务(在循环外提交)  COMMIT;  
END;  
/-- 截断临时表(如果需要重新填充)
TRUNCATE TABLE TMP_GET_ACTURAL_TABLE_COUNT;/
-- 调用存储过程(如果需要)
BEGINGET_ACTURAL_TABLE_COUNT(1);
END;
/
-- 查询临时表SELECT *FROM TMP_GET_ACTURAL_TABLE_COUNT
ORDER BY UPPER(table_name);/

相关文章:

  • 微服务架构拆分策略与实践
  • 前后端分离集成CAS单点登录
  • Redis配置文件详解(上)
  • 【C++】——vector深度剖析模拟实现
  • 命名导出和默认导出的用法区别
  • RabbitMQ08_保证消息可靠性
  • 2、在LVGL模拟器中了解部件的基础属性
  • 智慧城市主要运营模式分析
  • 【后端开发】JavaEE初阶——计算机是如何工作的???
  • 常见的TTL,RS232,RS485,IIC,SPI,UART之间的联系和区别
  • YOLOv8 Flask整合问题
  • 什么是Agent智能体?
  • 2024年信息安全企业CRM选型与应用研究报告
  • 探索 Android DataBinding:实现数据与视图的完美融合
  • 中间件:maxwell、canal
  • httpie使用详解
  • JavaSE小实践1:Java爬取斗图网站的所有表情包
  • JS 面试题总结
  • PAT A1017 优先队列
  • Python socket服务器端、客户端传送信息
  • Selenium实战教程系列(二)---元素定位
  • 检测对象或数组
  • 快速构建spring-cloud+sleuth+rabbit+ zipkin+es+kibana+grafana日志跟踪平台
  • 罗辑思维在全链路压测方面的实践和工作笔记
  • 使用parted解决大于2T的磁盘分区
  • 事件委托的小应用
  • 微信开源mars源码分析1—上层samples分析
  • 深度学习之轻量级神经网络在TWS蓝牙音频处理器上的部署
  • Java数据解析之JSON
  • ​ 无限可能性的探索:Amazon Lightsail轻量应用服务器引领数字化时代创新发展
  • #162 (Div. 2)
  • #window11设置系统变量#
  • $.each()与$(selector).each()
  • ${ }的特别功能
  • (2022版)一套教程搞定k8s安装到实战 | RBAC
  • (2024,LoRA,全量微调,低秩,强正则化,缓解遗忘,多样性)LoRA 学习更少,遗忘更少
  • (C++17) std算法之执行策略 execution
  • (Demo分享)利用原生JavaScript-随机数-实现做一个烟花案例
  • (MIT博士)林达华老师-概率模型与计算机视觉”
  • (python)数据结构---字典
  • (附表设计)不是我吹!超级全面的权限系统设计方案面世了
  • (附源码)spring boot建达集团公司平台 毕业设计 141538
  • (附源码)ssm跨平台教学系统 毕业设计 280843
  • (论文阅读30/100)Convolutional Pose Machines
  • (源码分析)springsecurity认证授权
  • (转)Oracle 9i 数据库设计指引全集(1)
  • (转)详解PHP处理密码的几种方式
  • .JPG图片,各种压缩率下的文件尺寸
  • .NET 5种线程安全集合
  • .NET CORE 第一节 创建基本的 asp.net core
  • .Net 转战 Android 4.4 日常笔记(4)--按钮事件和国际化
  • .NET正则基础之——正则委托
  • .sh 的运行
  • :如何用SQL脚本保存存储过程返回的结果集
  • @cacheable 是否缓存成功_让我们来学习学习SpringCache分布式缓存,为什么用?