2012-07-26 85 views
0
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)Month_space

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: [email protected] 
    prompt TO: [email protected] 
    prompt cc: [email protected] 
    prompt From: [email protected] 
    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  

回答

0

额外的循环中,您现在有输出永远不会终止,所以执行该过程将出现挂起,至少直到用完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 
    ) 
); 

您可以使用插入到新表,但不知道你甚至不需要真的,如果你只从过程中产生输出 - 尚不清楚,如果这是这种情况下,虽然你似乎不想显示所有你计算的统计数据。

我也不确定你的统计数据有多大意义。您似乎在计算任意月数的增长率,然后通过将该比率应用于数据库整个生命周期的平均值而不是目前的大小来预测未来的大小,而您似乎并未收集这些数据 - 您有现在的平均水平,这不是一回事。

+0

谢谢你的回应。 但我仍然想知道如何使用选择语句在程序之外看到上述格式的输出?我删除该循环,因为它不是必需的,它的工作正常。我只需要找到一种方法来使用select语句以上述格式显示。 谢谢 – racerxnox 2012-07-27 19:26:47

+0

@ user1554963 - 原始问题在PL/SQL块中显示,但是......好的。查询没有任何格式,客户可以选择格式化;那么你会在哪里运行查询?一个SQL * Plus脚本?这三个'db_type'部分在你的问题中看起来略有不同,我已经编辑过它,所以外观相同,但不知道这是否是你真正想要的 - 你可以更新以准确显示你需要的东西,如果不是。 – 2012-07-28 19:12:12

+0

谢谢Alex。 我将为sql文件设置一个shell脚本,将文件缓存到html主体中,每天通过电子邮件发送给整个数据库团队,使用cronjob报告数据库空间。所以程序中的显示没有达成一致,这只是电子邮件正文中的基因输出,因为select语句在表格格式中给出了适当的输出。 我l上面的SQL文件,也是HTML的示例输出 – racerxnox 2012-07-30 19:48:11