ORACLE查询数据库下所有表中所有字段的数据量及为空数据量为空率及最大更新时间最小更新时间

先创建一张表,该表中包含该库下的所有表,以及时间更新字段等。

此表的作用是为了遍历表及时间字段,也为了标识表含义等。

之后创建另一张表 ,该表中的字段分别为 表名、字段名、字段数据为空量、字段中数据总量、字段为空率及最小更新时间最大更新时间。

接下来就是存储过程了。

CREATE OR REPLACE PROCEDURE "TABLEFIELD" 
AS
        V_SQL VARCHAR2(2000);
        V_FIELD VARCHAR2(200);
        V_NUM INT:='0';
        V_T_NUM INT:='0';
        V_TABLENAME VARCHAR2(200);
        V_COUNT INT:='0';
        V_T_COUNT INT:='6';
        V_BUSTIMEFIELD    VARCHAR2(200);
     

    --将表名及时间字段从表中取出 插入到游标中           
    CURSOR  TAB_CURSOR IS 
    SELECT  TABLENAME,BUSTIMEFILED  FROM  DIC_TABLE ORDER BY TABLENAME;  
    
    --将表名及所有的字段从系统表中取出插入到游标中
    CURSOR  EMP_CURSOR(V_TABLENAME ALL_TAB_COLUMNS.TABLE_NAME%TYPE) IS 
                        SELECT  COLUMN_NAME  FROM  ALL_TAB_COLUMNS  
                        WHERE  TABLE_NAME=V_TABLENAME;
        
 -- 定义一个表示表中一行记录的变量
TAB TAB_CURSOR%ROWTYPE;
EMP EMP_CURSOR%ROWTYPE;

BEGIN

--先删除表中的数据    

DELETE FROM DIC_TABLEINFO;
  --打开游标开始循环  因为是两个游标,一个是表名的游标,另一个是字段的游标 所以要嵌套游标进行循环。
  OPEN TAB_CURSOR;
  LOOP
  FETCH TAB_CURSOR INTO TAB ;
  EXIT WHEN  TAB_CURSOR%NOTFOUND;    
        
                        
                        BEGIN
                        OPEN EMP_CURSOR(TAB.TABLENAME); 
                        LOOP
                        FETCH  EMP_CURSOR  INTO EMP;
                        EXIT WHEN  EMP_CURSOR%NOTFOUND;    
                        
                        

                                DBMS_OUTPUT.PUT_LINE(EMP.COLUMN_NAME);
                                --插入字段名称
                                V_SQL :='INSERT INTO DIC_TABLEINFO(CLONAME) VALUES('''||EMP.COLUMN_NAME||''')'; 
                                EXECUTE IMMEDIATE V_SQL;
                                COMMIT;    
                                
                                --更新字段中为NULL的数据量
                                V_SQL :='UPDATE DIC_TABLEINFO SET COLCOUNT=
                                ( SELECT COUNT(*) AS NUM FROM  '||TAB.TABLENAME||' WHERE '||EMP.COLUMN_NAME||' IS  NULL)
                                WHERE CLONAME='''||EMP.COLUMN_NAME||''' AND TABLE_NAME IS NULL';
                                EXECUTE IMMEDIATE V_SQL;
                                COMMIT;    

                                --更新表中字段的总量
                                --DBMS_OUTPUT.PUT_LINE(V_SQL);
                                V_SQL :='UPDATE DIC_TABLEINFO SET  TOTALCOUNT=(SELECT COUNT(*)                                                                           FROM '||TAB.TABLENAME||') WHERE TABLE_NAME IS NULL';
                                EXECUTE IMMEDIATE V_SQL;
                                COMMIT;    
                                
                                --更新为NULL百分比(保留四位小数),当数据总量为零时,直接设置百分比为0
                                UPDATE DIC_TABLEINFO SET  PERSENT=CASE
                                WHEN CAST(TOTALCOUNT AS FLOAT)=0 THEN 0
                                ELSE (ROUND(CAST(COLCOUNT AS FLOAT)/CAST(TOTALCOUNT AS FLOAT),2))
                                END;
                                
                                
                        END LOOP;   
                        CLOSE EMP_CURSOR;         
                        END;

                                --更新数据中的表名
                                V_SQL :='UPDATE DIC_TABLEINFO SET  TABLE_NAME ='''||TAB.TABLENAME||''' WHERE TABLE_NAME IS NULL';
                                EXECUTE IMMEDIATE V_SQL;
                                COMMIT; 
                            

                                --更新最大业务时间
                                V_SQL :='UPDATE DIC_TABLEINFO SET  MAXDATE=(SELECT MAX('||TAB.BUSTIMEFILED||')  FROM '||TAB.TABLENAME||') WHERE TABLE_NAME='''||TAB.TABLENAME||'''';
                                EXECUTE IMMEDIATE V_SQL;
                                COMMIT;
                                --更新最小业务时间
                                V_SQL :='UPDATE DIC_TABLEINFO SET  MINDATE=(SELECT MIN('||TAB.BUSTIMEFILED||')  FROM '||TAB.TABLENAME||') WHERE TABLE_NAME='''||TAB.TABLENAME||'''';
                                EXECUTE IMMEDIATE V_SQL;
                                COMMIT;                                   
                END LOOP;   
                CLOSE TAB_CURSOR;         
                END;

到此为止,在外面调用以下即可获取到表中想要的字段了。

猜你喜欢

转载自blog.csdn.net/qq_37823979/article/details/97938528