2012-07-26 202 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