如何用更多的游标编写pl / sql程序包体,并将它们作为varchar2

时间:2013-10-24 06:00:56

标签: sql stored-procedures plsql oracle11g

我是oracle pl / sql的新手。我想编写代码来获取表空间信息和数据库锁定状态,我想将它们输出为varchar2。我的代码给了我错误

** PACKAGE BODY FINAL_PACKAGE的错误:我将其作为** SYS AS SYSDBA运行

LINE/COL ERROR
11/13    PLS-00103: Encountered the symbol "SELECT" when expecting one of
         the following:
         ( ; is return 

第11行是

  

11 CURSOR选择a.TABLESPACE_NAME为

代码是,

CREATE OR REPLACE PACKAGE final_package as
     PROCEDURE final_procedure(var1 in varchar2, dbinfo out varchar2);
 END final_package;                                         
/


CREATE OR REPLACE PACKAGE BODY final_package IS

       PROCEDURE final_procedure(var1 in varchar2, dbinfo out varchar2) IS

        BEGIN
          IF var1 = 'a'
         ------  /* get tablespaces name, percentage */ ----
         THEN 
         DECLARE
            tsinfo varchar(500); ---- /* i want to put tablespaces result to this tsinfo */----

            CURSOR tbsp select a.TABLESPACE_NAME as
              Tablespace,round((1-((a.BYTES-nvl(b.BYTES,0))/a.BYTES))*100,2)
              AS Percentages from (select TABLESPACE_NAME, sum(BYTES) BYTES from
              sys.dba_data_files group by TABLESPACE_NAME) a,
              (select TABLESPACE_NAME, sum(BYTES) BYTES from sys.dba_free_space
                group by TABLESPACE_NAME) b
               where a.TABLESPACE_NAME = b.TABLESPACE_NAME (+)
              order by ((a.BYTES-b.BYTES)/a.BYTES) desc;

        BEGIN

            FOR each_data in tbsp
             LOOP
                 FETCH tbsp INTO tsinfo; --- /* i want to put tablespaces result to this tsinfo */ ---
             END LOOP;
            CLOSE tbsp;

          ----   /* get database lock status */ ----
         ELSIF var1 = 'b' THEN
             DECLARE lockinfo varchar(1500);
             CURSOR lock_info  SELECT vh.sid locking_sid,
                                vw.sid waiter_sid,
                                vs.status status,
                                vs.program program_holding,
                                vsw.program program_waiting
                               FROM v$lock vh, v$lock vw,
                                    v$session vs, v$session vsw
                               WHERE(vh.id1, vh.id2) IN 
                                    (SELECT id1, id2
                                       FROM v$lock
                                      WHERE request = 0
                                    INTERSECT 
                                     SELECT id1, id2
                                      FROM v$lock
                                      WHERE lmode = 0)
                                     AND vh.id1 = vw.id1
                                     AND vh.id2 = vw.id2
                                     AND vh.request = 0
                                     AND vw.lmode = 0
                                     AND vh.sid = vs.sid
                                     AND vw.sid = vsw.sid;

        BEGIN

            FOR each_data in lockinfo
                LOOP
             FETCH lock_info INTO lockinfo; -- i want to put database lock  result to this tsinfo
                END LOOP;
             CLOSE lock_info;

     END IF;   
  END;
 END;    
 /

2 个答案:

答案 0 :(得分:0)

更改为

CURSOR tbsp选择a.TABLESPACE_NAME为

答案 1 :(得分:0)

顺便说一句,我假设你有SQL Server背景。我对你的代码做了一些修复。请记住,即使您循环通过光标,您仍然只返回一个最新值。要改变它,你必须使用集合,即:嵌套表,关联数组。您的代码仍然无效,因为在光标中您选择了多个列,并尝试将其分配给包含单个值的变量。

尝试使用收藏品并发布您的答案。

代码:

CREATE OR REPLACE PACKAGE final_package IS

     PROCEDURE final_procedure(var1 IN VARCHAR2, dbinfo OUT VARCHAR2);

END final_package;



CREATE OR REPLACE PACKAGE BODY final_package IS

    PROCEDURE final_procedure(var1 IN VARCHAR2, dbinfo OUT VARCHAR2)
    IS
        -- declare variables
        tsinfo   varchar(500);
        lockinfo varchar(1500);

        -- declare cursors
        CURSOR tbsp IS
            select a.TABLESPACE_NAME as
            "TABLESPACE",round((1-((a.BYTES-nvl(b.BYTES,0))/a.BYTES))*100,2)
            AS Percentages from (select TABLESPACE_NAME, sum(BYTES) BYTES from
            sys.dba_data_files group by TABLESPACE_NAME) a,
            (select TABLESPACE_NAME, sum(BYTES) BYTES from sys.dba_free_space
            group by TABLESPACE_NAME) b
            where a.TABLESPACE_NAME = b.TABLESPACE_NAME (+)
            order by ((a.BYTES-b.BYTES)/a.BYTES) desc;

        CURSOR lock_info IS
            SELECT vh.sid locking_sid,
            vw.sid waiter_sid,
            vs.status status,
            vs.program program_holding,
            vsw.program program_waiting
            FROM v$lock vh, v$lock vw,
            v$session vs, v$session vsw
            WHERE(vh.id1, vh.id2) IN 
            (SELECT id1, id2
            FROM v$lock
            WHERE request = 0
            INTERSECT 
            SELECT id1, id2
            FROM v$lock
            WHERE lmode = 0)
            AND vh.id1 = vw.id1
            AND vh.id2 = vw.id2
            AND vh.request = 0
            AND vw.lmode = 0
            AND vh.sid = vs.sid
            AND vw.sid = vsw.sid;
    BEGIN
        IF var1 = 'a' THEN
            -- open, loop and close
            FOR each_data in tbsp
            LOOP
                FETCH tbsp INTO tsinfo;
            END LOOP;
        ELSIF var1 = 'b' THEN
            -- open, loop and close
            FOR each_data in lockinfo
            LOOP
                FETCH lock_info INTO lockinfo;
            END LOOP;
        END IF;
    END final_procedure;

END final_package;