【问题标题】:Displaying the contents according to their heading type根据标题类型显示内容
【发布时间】:2012-07-25 03:42:58
【问题描述】:
I am new to SQL. My doubt is how to display the output inside the procedure like this.
I have various databases and its type and the current size all in one table 'predict_storage'
I want to display the output as:

    UAT:
        TMAP: 100G
        TCIG: 200G

    QA:
        QMAP: 100G
        QCIG: 200G

    DR:
        DRMAP: 100G
        DRCIG: 200G

其中 UAT 是数据库类型,TMAP,TCIG 是数据库,当前大小为 100g。所以我希望输出像这样根据数据库类型分类。

代码如下:

    CREATE OR REPLACE PROCEDURE test11 IS

        db_original_name_var varchar2(30);
        db_type varchar2(20);
        db_name varchar2(40);
        Used_space_var NUMBER;

        MAX_Used_space_monthvar NUMBER;
        RATE NUMBER;
        avg_space_future_min NUMBER;
        avg_space_future_max NUMBER;
        avgsp NUMBER;
        avg_space_3m NUMBER;
        avg_space_6m Number;
        avg_space_yr NUMBER;

        CURSOR db_list_cur is
        select original_db_name,database_type
        from database_list;

    Begin
      open db_list_cur;
      LOOP
      fetch db_list_cur
      into db_original_name_var,db_type;
     EXIT WHEN db_list_cur%NOTFOUND;

           select substr(avg(ave_used_space),0,6) INTO Used_space_var from month_space where db_original_name_var=database_name;
          select substr(max(ave_used_space),0,6) INTO MAX_Used_space_monthvar from month_space where db_original_name_var=database_name;

       --rate calc
     RATE := (MAX_Used_space_monthvar-Used_space_var)/Used_space_var;

     avg_space_future_max:=(Used_space_var)+(Used_space_var* RATE);
    avg_space_future_min:=(Used_space_var)-(Used_space_var* RATE);
    avgsp := (avg_space_future_max + avg_space_future_min)/2;

    avg_space_3m :=(avgsp)+(avgsp* rate* 3);
    avg_space_6m :=(avgsp)+(avgsp* rate* 6);
    avg_space_yr :=(avgsp)+(avgsp* rate* 12);

    insert into Predict_report
    (
    database_name ,
    Grwoth_rate ,
    Current_AVERAGE,
    Space_3mn,
    SPACE_6mn,
    Space_yr,
    database_type
    )
    values
    (
    db_original_name_var,
    RATE,
    round(avgsp,3),
    round(avg_space_3m,3),
    round(avg_space_6m,3),
    round(avg_space_yr,3),
    db_type
    );
    commit;

        loop
        dbms_output.put_line(db_type||':');
        select database_name into db_name from predict_report  where database_type=db_type;
        dbms_output.put_line(db_name);
        END LOOP;

       END LOOP;
       close db_list_cur;


    END;
    /

我的桌子是 1) 存储信息

    DB_ID               NUMBER(38)
    DATABASE_NAME       VARCHAR2(50)
    DATABASE_SIZE       NUMBER
    TIME_STAMP          DATE
    FREE_SPACE          VARCHAR2(50)
    DATA_LINK_NAME      VARCHAR2(50)
    CUSTOMER_SPACE      NUMBER
    DATABASE_TYPE       VARCHAR2(30)
    USED_SPACE          NUMBER

2) Database_list

    DB_ID               NUMBER
    DB_NAME             VARCHAR2(50)
    DATALINK_NAME       VARCHAR2(50)
    DATABASE_TYPE       VARCHAR2(20)
    ORIGINAL_DB_NAME    VARCHAR2(30)

3)预测报告

    DATABASE_NAME       NOT NULL VARCHAR2(50)
    GRWOTH_RATE         NUMBER
    CURRENT_AVERAGE     NUMBER
    SPACE_3MN           NUMBER
    SPACE_6MN           NUMBER
    SPACE_YR            NUMBER
    DATABASE_TYPE       VARCHAR2(20)

4) 月份空间

    DATABASE_NAME       NOT NULL VARCHAR2(50)
    GRWOTH_RATE         NUMBER
    CURRENT_AVERAGE     NUMBER
    SPACE_3MN           NUMBER
    SPACE_6MN           NUMBER
    SPACE_YR            NUMBER
    DATABASE_TYPE       VARCHAR2(20)

-----sql文件是

        set echo off numf 999G999G999G999 lin 32000 trims on pages 50000 head on feed off     markup html off
    alter session set nls_numeric_characters='.''' nls_date_format='Day DD. Month, YYYY';
    spool /tmp/report.html
--prompt To: jialin.zhu@synchronoss.com
    prompt TO: varun.jain@synchronoss.com
    prompt cc: varun.jain@synchronoss.com
    prompt From: varun.jain@synchronoss.com
    prompt Subject: Daily space report
    prompt Content-type: text/html
    prompt MIME-Version: 1.0
    set markup html on entmap off table 'BORDER="2" BGCOLOR="white" FONTCOLOR="black"'
    prompt <i>Good morning, </i>
    prompt <i>Here is the Space report as on &_DATE</i>
    prompt <i>Kind Regards, </i>

------------------------------------------------------------------------------------------------------------------------------------------------
    prompt <br/><h3>Database Space Report</h3>

    set serveroutput on
    CLEAR COLUMNS
    Set HEADING ON
    Set COLSEP ,
    SET PAGESIZE 20000
    SET timing off feedback off verify off echo off

    prompt <br/><h3> Environment Space Summary</h3>
    column database_type heading 'Database Type'
    column Sum(current_average) format 9999 HEADING 'Total Space in GB'
    select database_type,Sum(current_average) from predict_report group by database_type;
--------------------------------------------------------------------------------------------------------------------------------------------------

    prompt <br/><h3> DR database Summary</h3>
    COLUMN ('THETOTALSPACEINDRDATABASES:'||SUM(CURRENT_AVERAGE)||''||'GB') format 9999 heading     'total Space in DR database'
    select ('The total space in DR databases :' ||Sum(current_average)||' '||'GB') from     predict_report where DATABASE_TYPE not in ('UAT','QA');
------------------------------------------------------------------------------------------------------------------------------------------
    prompt <br/><h3> databases  Summary</h3>
    column database_name format a30 heading ' DATABASE NAME'
    column round(GRWOTH_RATE*100,0)||'%'  heading 'GROWTH RATE'
    COLUMN CURRENT_AVERAGE FORMAT 9999 HEADING 'TODAYS SPACE in GB'
    COLUMN SPACE_3MN FORMAT 9999 HEADING 'SPACE AFT 3 MONTHS in GB'
    COLUMN SPACE_6MN FORMAT 9999 HEADING 'SPACE AFT 6 MONTHS in GB'
    COLUMN SPACE_YR FORMAT 9999 HEADING 'SPACE AFT A YEAR in GB'
    truncate table Predict_report;
    set serveroutput on
    exec report;
    SELECT         database_name,round(GRWOTH_RATE*100,0)||'%',current_average,space_3mn,space_6mn,space_yr     FROM Predict_report;

---------------------------------------------------------------------------------
    prompt <br/><h3>Database Space Summary</h3>
    column sum(current_average) FORMAT 9999 heading 'Total Space in GB'
    column sum(space_3mn) FORMAT 9999  heading 'Total Space in 3 months in GB'
    column sum(space_6mn) FORMAT 9999  heading 'Total Space in 6 months in GB'
    column sum(space_yr) FORMAT 9999 heading 'Total Space in 1 year in GB'
    select sum(current_average),sum(space_3mn),sum(space_6mn),sum(space_yr) from             Predict_report ;
    spool off;

---------to send the mail----------------

    host /usr/sbin/sendmail -t </tmp/report.html

收到的电子邮件中的输出类似于(它在 EMAIL 中以表格形式)

DATABASE NAME   GROWTH RATE     TODAYS SPACE in GB  SPACE AFT 3 MONTHS in GB    SPACE AFT 6 MONTHS in GB    SPACE AFT A YEAR in GB 
CLNK    0%  199     200     200     202 
CCIG    0%  562     563     563     565 
DTXN    5%  330     377     424     518 
DCIG    0%  414     416     418     422 
QMAP    0%  16  16  17  17 
QLNP    0%  44  44  44  44 
QHTS    1%  32  32  33  34 
QFKP    1%  37  38  39  41 
QSAG    0%  168     169     170     172 
CSAG    0%  812     815     818     824 
LTATG   0%  25  25  25  25 
QCIG    0%  208     209     209     211 
TLNP    0%  341     341     341     341 
TMAP    0%  60  61  61  62 
TSAG    0%  223     226     228     

【问题讨论】:

    标签: oracle loops cursor procedure


    【解决方案1】:

    您现在用于输出的额外循环永远不会终止,因此执行过程似乎会挂起,至少在您用完dbms_output 缓冲区空间之前;并且不检索当前值。而且它在错误的位置,因为它会在每次循环中显示该类型的所有数据库的数据,所以你会得到重复(充其量)。

    虽然这似乎不是一种明智的做法,尤其是因为您假设该过程将始终由可以显示输出并启用输出的东西运行,但您可以执行类似这样的操作, 之后 close db_list_cur:

    db_type := null;
    for r in (select database_type, database_name, current_average
        from predict_report
        order by database_type, database_name)
    loop
        if db_type is null or db_type != r.database_type then
            dbms_output.put_line(r.database_type || ':');
            db_type := r.database_type;
        end if;
        dbms_output.put_line(r.database_name ||' '||
            to_char(nvl(r.current_average, 0), '999990.00') ||'G');
    end loop;
    

    ... 或基于您要插入的数据在主循环中,而不是在末尾查询表(因为它们应该匹配);但无论您使用循环还是更简单的insert into predict_report select ...,这都将起作用。

    您不需要使用游标来计算统计信息或填充表格;你根本不需要 PL/SQL。您可以将两个表连接在一起并从返回值中计算出数字。像这样的事情会做到这一点:

    select database_name,
        rate as grwoth_rate,
        avg_used_space as current_average,
        avg_used_space + (avg_used_space * rate * 3) as space3mn,
        avg_used_space + (avg_used_space * rate * 6) as space6mn,
        avg_used_space + (avg_used_space * rate * 12) as spaceyr,
    database_type
    from (
        select database_name,
            database_type,
            avg_used_space,
            max_used_space,
            (max_used_space - avg_used_space)/avg_used_space as rate
        from (
            select dl.original_db_name as database_name,
                dl.database_type,
                trunc(avg(ave_used_space), 2) as avg_used_space,
                trunc(max(ave_used_space), 2) as max_used_space
            from database_list dl
            join month_space ms on ms.database_name = dl.original_db_name
            group by dl.original_db_name,
                dl.database_type
        )
    );
    

    您可以使用它来插入新表,但不确定是否真的需要它,如果您只是在过程中生成输出 - 不清楚是否是这种情况,尽管您似乎不想要显示您正在计算的所有统计信息。

    不过,我也不确定您的统计数据是否有意义。您似乎正在计算任意月数的增长率,然后通过将该增长率应用于数据库生命周期内的平均值而不是当前大小来预测未来的大小,您似乎没有收集到 - 您有当前的平均值,这不是一回事。

    【讨论】:

    • 感谢您的回复。但是我仍然想知道如何在过程之外使用 select 语句以我上面提到的那种格式查看输出?我删除了该循环,因为它不是必需的并且它工作正常。我只需要找到一种方法来使用选择语句以上述格式显示。谢谢
    • @user1554963 - 原始问题显示在 PL/SQL 块内,但是... 好的。查询实际上没有任何格式,客户端可以选择对其进行格式化;那么您将在哪里运行查询? SQL*Plus 脚本?三个db_type 部分在您的问题中的外观略有不同,我已经对其进行了编辑,因此看起来相同,但不知道这是否是您真正想要的 - 如果不是,您能否更新以准确显示您需要的内容。
    • 谢谢亚历克斯。我将为 sql 文件设置一个 shell 脚本,以将文件假脱机为 html 正文,该正文每天通过电子邮件发送给整个数据库团队,使用 cronjob 报告数据库空间。因此,程序的显示没有达成一致,这只是电子邮件正文中的一般输出,其中 select 语句以表格格式给出了正确的输出。我发布了上面的 sql 文件以及 html 的示例输出
    • @user1554963 - 我不确定我是否理解;你现在的输出有什么问题?
    • 程序在邮件正文中没有给出html表格格式的输出。它的形式很随意,就像每行不被部门接受的文字一样。他们希望它以表格形式出现。目前只有选择语句在 html 中给出
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-02
    • 1970-01-01
    相关资源
    最近更新 更多