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

news/2024/9/27 18:36:33 标签: 数据库, sql, oracle, 达梦

背景

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

源SQL

需要用目的用户去执行

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

需要用目的用户去执行

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用户可以执行任何模式下的表信息的统计

-- 删除并重新创建临时表
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);

/

http://www.niftyadmin.cn/n/5679267.html

相关文章

【多样化的思想】基于执行档案的测试

下面我们讨论另一种关于多样性的观点。我们知道,对被测对象而言,测试输入空间代表的是各种可能的外部环境条件。如果两个测试输入点距离比较远,说明在这两个点上,被测对象所面对的外部环境条件很不一样,所以我们说&…

C++简单缓冲区类设计

目录 1.引言 2.静态缓冲区 3.动态缓冲区 4.数据引用类 5.自动数据引用类 6.几种缓冲区的类关系图 7.注意事项 8.完整代码 1.引言 在C中,设计静态和动态缓冲区类时,需要考虑的主要差异在于内存管理的方式。静态缓冲区类通常使用固定大小的内存区域…

C:数据在内存中的存储

目录 一、整数在内存中的存储 二、大小端字节序 2.1 大小端字节序的介绍 2.2 为什么有大小端之分(了解即可) 2.3 判断大小端的代码实现 三、浮点数的数据存储 3.1 浮点数的存储 3.2 浮点数存储的过程 3.2.1 对于有效数字M 3.2.1 对于指数E 3.3…

前端导出页面PDF

import html2canvas from html2canvas import { jsPDF } from jspdf import { Loading } from element-ui let downloadLoadingInstance// 导出页面为PDF格式---使用插件html2canvas和jspdf插件 export function exportPDF(fileName, node) {downloadLoadingInstance Loading.…

药物临床试验机构备案信息数据库查询方法(支持数据下载)

药物临床试验机构备案管理信息平台是一个由国家药品监督管理局组织建立的系统,该平台向社会开放,提供药物临床试验机构的省份&地区、备案号、机构名称、地址、联系人、联系方式、备案状态、备案专业和主要研究者(专业名称、主要研究者、职称、专业备…

苹果手机如何录屏?IOS 自带工具与嗨格式录屏大师 APP 详解

在当今数字化时代,手机录屏功能变得越来越重要,无论是记录游戏精彩瞬间、制作教学视频,还是分享操作演示,都离不开它。今天,我们就来详细了解一下手机如何录屏视频,重点介绍 IOS 自带录屏工具以及嗨格式录屏…

webpack与vite读取base64图片

某些特殊场景下,需要使用base64渲染图片 data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAkGBxETEhUSEBAVFhIXEhIXFRYYFxcVFhYWFxYWFxcXFRcYHSggGBonIBcVITEhJSkrLi4uGB8zODMsOCgtLysBCgoKDg0OGxAQGjMlHyUrLTcuKzMrNy0tLi0tKzUtLS0vLS4rKysrLisrLTYtLTU…

探索GraphRAG:用yfiles-jupyter-graphs将知识库可视化!

yfiles-jupyter-graphs 可视化 GraphRAG 结构 前言 前面我们通过 GraphRag 命令生成了知识库文件 parquet,这节我们看一下如何使用 yfiles-jupyter-graphs 添加 parquet 文件的交互式图形可视化以及如何可视化 graphrag 查询的结果。 yfiles-jupyter-graphs 是一…