【PL/SQL系列】Oracle預存程序使用動態SQL

來源:互聯網
上載者:User

【PL/SQL系列】Oracle預存程序使用動態SQL

Oracle預存程序相信大家都比較瞭解,下面就為您介紹Oracle預存程序使用動態SQL的方法,希望對您能夠有所協助。

CREATE OR REPLACE PROCEDURE P_STAT_SCORE01
(
      PARA_EXAMGUID VARCHAR2,  -- 考試ID  A9093AE714AC47758A367B8813B99D1D,3216885E3B3148E3904908BD30BF9413,F8254D3E50F64819A996D1E369BBF053
      CUR OUT SYS_REFCURSOR
)
 
/****************************************************************************
名稱:P_STAT_SCORE02
功能描述:根據考試ID,取出班級,考試科目資訊
 
歷程記錄:
版本號碼  編輯時間  編輯人  修改描述
1.0.0    2016-4-7 CHEQNP    1.建立此預存程序,修改動態SQL語句,主要包括變數的使用和WHERE語句的書寫
 
注釋
 
入參出參描述:
PARA_EXAMGUID 考試ID
CUR            輸出遊標
 
*****************************************************************************/
 
AS
    -- 定義變數
    VAR_SQL CLOB;                -- 拼接SQL
    VAR_TEACHER_SQL CLOB;        -- 科任老師
    VAR_COURSENAME VARCHAR(200);  -- 科目名稱
   
BEGIN
 
    VAR_SQL := 'SELECT
              (CASE WHEN CLASSROOM_NAME IS NULL THEN ''合計'' ELSE MIN(CLASSROOM_NAME) END) AS 班級 ';
   
    -- 取應考人數,實考人數
    VAR_SQL := VAR_SQL || ' ,NVL2(CLASSROOM_NAME,
                    (SELECT COUNT(1) FROM TPRG_STUDENT a
                        LEFT JOIN TPRG_CLASSROOM b
                        ON a.CLASSROOM_ID = b.CLASSROOM_ID
                        WHERE b.CLASSROOM_NAME = T.CLASSROOM_NAME ),
                    (SELECT COUNT(1) FROM TPRG_STUDENT
                    WHERE CLASSROOM_ID
                    IN (SELECT CLASSROOM_ID
                    FROM V_FULL_SCORE
                    WHERE EXAMGUID = '''||PARA_EXAMGUID||'''
                    GROUP BY CLASSROOM_ID)))  應考人數
              ,COUNT(DISTINCT STUDID) AS 實考人數 ';
 
    -- 定義遊標myCusor
    -- 根據考試ID查詢考試科目,並按照COURSEID產生科目順序
    DECLARE CURSOR myCusor IS SELECT COURSENAME FROM V_FULL_SCORE  WHERE EXAMGUID = ''||PARA_EXAMGUID||''
    GROUP BY COURSEID,COURSENAME
    ORDER BY COURSEID ASC;
      -- 開始使用遊標取資料
      BEGIN
            OPEN myCusor;
            LOOP
                FETCH myCusor INTO VAR_COURSENAME;
                -- 遊標取不到資料則退出
                EXIT WHEN myCusor%NOTFOUND;
               
                -- 動態拼接各科目SQL語句
                VAR_SQL := VAR_SQL || ' , ROUND(SUM(CASE COURSENAME WHEN '''||VAR_COURSENAME||''' THEN SCORE_SUM ELSE 0 END) / SUM(CASE COURSENAME WHEN '''||VAR_COURSENAME||''' THEN 1 ELSE NULL END),2) '||VAR_COURSENAME||'平均分
              , MAX(CASE COURSENAME WHEN '''||VAR_COURSENAME||''' THEN SCORE_SUM ELSE 0 END) '||VAR_COURSENAME||'最高分
              , SUM(CASE WHEN COURSENAME = '''||VAR_COURSENAME||''' AND SCORE_SUM >= FULLSCORE_SUM * 0.6 THEN 1 ELSE 0  END) '||VAR_COURSENAME||'_及格人數
              , ROUND(SUM(CASE WHEN COURSENAME = '''||VAR_COURSENAME||''' AND SCORE_SUM >= FULLSCORE_SUM * 0.6 THEN 1 ELSE 0 END) / SUM(CASE COURSENAME WHEN '''||VAR_COURSENAME||''' THEN 1 ELSE NULL END) * 100,2) '||VAR_COURSENAME||'_及格率
              , SUM(CASE WHEN COURSENAME = '''||VAR_COURSENAME||''' AND SCORE_SUM >= FULLSCORE_SUM * 0.8 THEN 1 ELSE 0 END) '||VAR_COURSENAME||'_優分人數
              , ROUND(SUM(CASE WHEN COURSENAME = '''||VAR_COURSENAME||''' AND SCORE_SUM >= FULLSCORE_SUM * 0.8 THEN 1 ELSE 0 END) / SUM(CASE COURSENAME WHEN '''||VAR_COURSENAME||''' THEN 1 ELSE NULL END) * 100,2) '||VAR_COURSENAME||'_優分率';
               
              VAR_TEACHER_SQL := VAR_TEACHER_SQL || ' NULL AS ' || VAR_COURSENAME||'_科任老師 , ';
               
            END LOOP;
            CLOSE myCusor;
      END;
       
      -- 科任教師部分字串去掉逗號
      VAR_TEACHER_SQL := SUBSTR(TRIM(VAR_TEACHER_SQL),1,LENGTH(TRIM(VAR_TEACHER_SQL))-1);
 
      -- 拼接科任教師部分
      VAR_SQL := VAR_SQL || ',' || VAR_TEACHER_SQL;
     
    --  按照班級名稱,科目名稱,學生得到每個學生總分
    --  根據班級進行分組
    VAR_SQL := VAR_SQL || ' FROM (
            SELECT CLASSROOM_NAME
                    ,COURSENAME
                    ,STUDID
                    ,STUD_NAME
                    ,SUM(SCORE) AS SCORE_SUM
                    ,SUM(FULLSCORE) AS FULLSCORE_SUM
                FROM V_FULL_SCORE
              WHERE EXAMGUID = '''||PARA_EXAMGUID||'''
                  GROUP BY
                      CLASSROOM_NAME 
                      ,COURSENAME
                      ,STUDID
                      ,STUD_NAME) T
        GROUP BY ROLLUP(CLASSROOM_NAME)';
 
    DBMS_OUTPUT.PUT_LINE(VAR_SQL);
     
    OPEN CUR FOR VAR_SQL;
 
END ;

Oracle資料庫之PL/SQL程式基礎設計 

PL/SQL Developer實用技巧分享

使用PL/Scope分析PL/SQL代碼 

在PL/SQL中使用日期類型

從一個案例看PL/SQL代碼片的編譯與運行

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.