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

背景

在一次Oracle迁移Dm的过程中,源库&目的库大小写均敏感,执行客户提供的SQL脚本的过程中发现,表ip_address被系统默认成了表IP_ADDRESS

经过分析,客户提供的SQL没有使用双引号,来确保Oracle和Dm数据库按照指定的大小写来识别表名,因此,做以下改写。

源SQL

需要用目的用户去执行

javascript 复制代码
declare 
    num number;
begin
    select count(1) 
      into 
           num 
      from user_tables 
     where table_name = 'TMP_GET_ACTURAL_TABLE_COUNT';
     
    if num > 0 then
        execute 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 
IS
    sqlstr varchar2(4000);
begin
    for 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_%'
    ) 
    loop
        execute 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

需要用目的用户去执行

javascript 复制代码
DECLARE
    num NUMBER;
BEGIN
    SELECT COUNT(1)
      INTO
           num
      FROM user_tables
     WHERE table_name = 'TMP_GET_ACTURAL_TABLE_COUNT';
    
    IF num > 0 THEN
        EXECUTE 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
IS
    sqlstr 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;

/
-- 调用存储过程(如果需要)
BEGIN
    GET_ACTURAL_TABLE_COUNT(1);
END;
/
-- 查询临时表
  SELECT * 
    FROM TMP_GET_ACTURAL_TABLE_COUNT 
ORDER BY UPPER(table_name);

/

通用SQL-(暂时未成功)

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

javascript 复制代码
-- 删除并重新创建临时表
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;

/
-- 调用存储过程(如果需要)
BEGIN
    GET_ACTURAL_TABLE_COUNT(1);
END;
/
-- 查询临时表
  SELECT *
    FROM TMP_GET_ACTURAL_TABLE_COUNT
ORDER BY UPPER(table_name);

/
相关推荐
小Tomkk10 分钟前
阿里云 RDS mysql 5.7 怎么 添加白名单 并链接数据库
数据库·mysql·阿里云
明月醉窗台1 小时前
qt使用笔记二:main.cpp详解
数据库·笔记·qt
沉到海底去吧Go2 小时前
【图片自动识别改名】识别图片中的文字并批量改名的工具,根据文字对图片批量改名,基于QT和腾讯OCR识别的实现方案
数据库·qt·ocr·图片识别自动改名·图片区域识别改名·pdf识别改名
老纪的技术唠嗑局2 小时前
重剑无锋,大巧不工 —— OceanBase 中的 Nest Loop Join 使用技巧分享
数据库·sql
未来之窗软件服务2 小时前
JAVASCRIPT 前端数据库-V6--仙盟数据库架构-—-—仙盟创梦IDE
数据库·数据库架构·仙盟创梦ide·东方仙盟·东方仙盟数据库
寒山李白2 小时前
MySQL复杂SQL(多表联查/子查询)详细讲解
sql·mysql·子查询·多表联查
一只爱撸猫的程序猿4 小时前
构建一个简单的智能文档问答系统实例
数据库·spring boot·aigc
nanzhuhe4 小时前
sql中group by使用场景
数据库·sql·数据挖掘
消失在人海中4 小时前
oracle sql 语句 优化方法
数据库·sql·oracle
Clang's Blog4 小时前
一键搭建 WordPress + MySQL + phpMyAdmin 环境(支持 PHP 版本选择 & 自定义配置)
数据库·mysql·php·wordpr