ORACLE的Packge

来源:互联网 发布:淘宝卖的夜磨牙垫好吗 编辑:程序博客网 时间:2024/04/29 10:19
01、ORACLE,PACKAGE 的作用    可以简化应用设计、提高应用性能、实现信息隐藏、子程序重载02、ORACLE中的 FUNCTION,PACKAGE,PACKAGE,BODIES,PROCEDURE 的区别和相同    FUNCTION有返回值,有参数;PROCEDURE无返回值,有参数: PACKAGE,PACKAGE BODY 是同时存在的,就像.H和.CPP文件,如果要外部调用的,就在 PACKAGE 里声明一下,包内调用的,只 要在 BODY 里写就行了。 PACKAGE 可包括 FUNCTION,PROCEDURE03、在 SQLSERVER 中,直接写个存储过程就可以调用。但是在ORACLE中,我看好多资料上说要想调用存储过程必须把存储过程放进包中才能调用?是否是这样?    不是,过程也可以单独写,单独调用04、PACKAGE 与 PACKAGE BODIES 有什么区别?    PACKAGE 只有各个方法的定义,BODIES 中涉及具体的实现05、我在存储过程就是 PROCEDURE 中写了个存储过程,再写个包名包含进去吗?还是可以直接在包中写包名:再把想写的存储过程直接写进包中就行啦呢?    不用06、写进包,要写进哪个?PACKAGES 还是 PACKAGE   BODIES    这两个是一体的,必须同时存在    PACKAGE,BODY,PACKAGE 都需要手工去写。    需要先创建PACKAGE(也就是包的定义),再创建BODY。增加包中的过程或者修改包中过程的输入参数个数等也是要先改 PACKAGE 再改 BODY 。01、什么是 REF 游标    动态关联结果集的临时对象。即在运行的时候动态决定执行查询。02、REF 游标 有什么作用?    实现在程序间传递结果集的功能,利用 REF CURSOR 也可以实现 BULK SQL,从而提高SQL性能。03、静态游标和REF 游标的区别是什么?    ①静态游标是静态定义,REF 游标是动态关联;    ②使用REF 游标需REF 游标变量。    ③REF 游标能做为参数进行传递,而静态游标是不可能的。04、什么是REF 游标变量?    REF游标变量是一种 引用 REF游标类型  的变量,指向动态关联的结果集。05、怎么使用  REF游标 ?    ①声明REF 游标类型,确定REF 游标类型;    ⑴强类型REF游标:指定RETRUN TYPE,REF 游标变量的类型必须和RETURN TYPE一致。      语法:TYPE REF 游标名 IS REF CURSOR RETURN  结果集返回记录类型;    ⑵弱类型REF游标:不指定RETURN TYPE,能和任何类型的CURSOR变量匹配,用于获取任何结果集。      语法:TYPE REF 游标名 IS REF CURSOR;    ②声明REF 游标类型变量;      语法:变量名  已声明REF 游标类型;    ③打开REF游标,关联结果集 ;      语法:OPEN   REF 游标类型变量 FOR 查询语句返回结果集;    ④获取记录,操作记录;      语法:FATCH    REF游标名 INTO 临时记录类型变量或属性类型变量列表;    ⑤关闭游标,完全释放资源;      语法:CLOSE   REF游标名;    例子:强类型REF游标    /*CONN SCOTT/TIGER*/    DECLARE    TYPE MYREFCURA IS  REF CURSOR RETURN EMP%ROWTYPE;    TYPE MYREFCURB IS  REF CURSOR RETURN EMP.ENAME%TYPE;    VREFCURA  MYREFCURA;    VREFCURB  MYREFCURB;    VTEMPA  VREFCURA%ROWTYPE;    VTEMPB  VREFCURB.ENAME%TYPE;    BEGIN      OPEN VREFCURA FOR SELECT * FROM EMP WHERE SAL > 2000;      LOOP        FATCH  VREFCURA INTO VTEMPA;        EXIT  WHEN  VREFCURA%NOTFOUND;        DBMS_OUTPUT.PUT_LINE(VREFCURA%ROWCOUNT||'  '|| VTEMPA.ENO||'  '||VTEMPA.ENAME ||'  '||VTEMPA.SAL)      END LOOP;      CLOSE VREFCURA;      DBMS_OUTPUT.PUT_LINE('-------------------------------------------------------------------------------------------------------');      OPEN VREFCURB FOR SELECT ENAME FROM EMP WHERE SAL > 2000;      LOOP        FATCH VREFCURB INTO  VTEMPB;        EXIT WHEN VREFCURB%NOTFOUND;        DBMS_OUTPUT.PUT_LINE(VREFCURB%ROWCOUNT||'  '||VTEMPB)      END LOOP;      CLOSE VREFCURB;      DBMS_OUTPUT.PUT_LINE('-------------------------------------------------------------------------------------------------------');      OPEN  VREFCURA  FOR SELECT  *  FROM   EMP   WHERE  JOB = 'CLERK';      LOOP        FATCH  VREFCURA INTO  VTEMPA;        EXIT  WHEN  VREFCURA%NOTFOUND;        DBMS_OUTPUT.PUT_LINE(VREFCURA%ROWCOUNT||'  '|| VTEMPA.ENO||'  '||VTEMPA.ENAME ||'  '||VTEMPA.SAL)      END LOOP;      CLOSE VREFCURA;    END;  例子:弱类型REF游标  /*CONN SCOTT/TIGER*/  DECLARE    TYPE MYREFCUR  IS  REF  CURSOR;    VREFCUR MYREFCUR;    VTEMP  VREFCUR%ROWTYPE;  BEGIN    CASE(&N)      WHEN  1 THEN OPEN VREFCUR  FOR SELECT   *   FROM EMP;      WHEN  2 THEN OPEN VREFCUR  FOR SELECT   *   FROM DEPT;    ELSE      OPEN VREFCUR  FOR SELECT   ENO,  ENAME  FROM EMP WHERE JOB = 'CLERK';    END CASE;    CLOSE VREFCUR;  END;06、怎样让REF游标作为参数传递?    --作为函数返回值    CREATE OR REPLACE FUNCTION RETURNACURSOR RETURN SYS_REFCURSOR    IS      V_CSR SYS_REFCURSOR;    BEGIN      OPEN V_CSR FOR SELECT A1 FROM TEST3;      RETURN V_CSR;    END;    /    DECLARE      C SYS_REFCURSOR;      A1 CHAR(2);    BEGIN      C:=RETURNACURSOR;      LOOP      FETCH C INTO A1;        EXIT WHEN C%NOTFOUND;        DBMS_OUTPUT.PUT_LINE(A1);      END LOOP;      CLOSE C;    END;    /    --作为参数    CREATE OR REPLACE PROCEDURE PROC_REF_CURSOR (RC IN SYS_REFCURSOR) AS      V_A NUMBER;      V_B VARCHAR2(10);    BEGIN    LOOP      FETCH RC INTO V_A, V_B;      EXIT WHEN RC%NOTFOUND;      DBMS_OUTPUT.PUT_LINE(V_A || ' ' || V_B);    END LOOP;    END;    /    DECLARE      V_RC SYS_REFCURSOR;    BEGIN      OPEN V_RC FOR SELECT A1,A2 FROM TEST3;      PROC_REF_CURSOR(V_RC);      CLOSE V_RC;    END;    /REF CURSOR 示例包括下列三个 VISUAL BASIC 示例,演示如何使用 REF CURSOR。在 OracleDataReader 中检索 REF CURSOR 参数此示例执行一个 PL/SQL 存储过程,返回 REF CURSOR 参数,并将值作为 OracleDataReader 读取。使用 OracleDataReader 从多个 REF CURSOR 检索数据此示例执行一个 PL/SQL 存储过程,返回两个 REF CURSOR 参数,并使用 OracleDataReader 读取值。使用一个或多个 REF CURSOR 填充 DataSet此示例执行一个 PL/SQL 存储过程,返回两个 REF CURSOR 参数,并使用返回的行填充 DATASET。要使用这些示例,可能需要创建 ORACLE 表,并且必须创建 PL/SQL 包和包正文。创建 ORACLE 表这些示例使用 ORACLE SCOTT/TIGER 架构中定义的表。大多数 ORACLE 安装均包括 ORACLE SCOTT/TIGER 架构。如果此架构不存在,可以使用 {ORACLEHOME}RDBMSADMINSCOTT.SQL 中的 SQL 命令文件创建供这些示例使用的表和索引。创建 ORACLE 包和包正文这些示例要求服务器上存在以下 PL/SQL 包和包正文。在 ORACLE 服务器上创建以下 ORACLE 包CREATE OR REPLACE PACKAGE BODY CURSPKG AS  PROCEDURE OPEN_ONE_CURSOR (N_EMPNO IN NUMBER,IO_CURSOR IN OUT T_CURSOR)  IS    V_CURSOR T_CURSOR;  BEGIN    IF N_EMPNO <> 0 THEN      OPEN V_CURSOR FOR      SELECT EMP.EMPNO, EMP.ENAME, DEPT.DEPTNO, DEPT.DNAME FROM EMP, DEPT      WHERE EMP.DEPTNO = DEPT.DEPTNO AND EMP.EMPNO = N_EMPNO;    ELSE      OPEN V_CURSOR FOR      SELECT EMP.EMPNO, EMP.ENAME, DEPT.DEPTNO, DEPT.DNAME FROM EMP, DEPT      WHERE EMP.DEPTNO = DEPT.DEPTNO;    END IF;    IO_CURSOR := V_CURSOR;  END OPEN_ONE_CURSOR;  PROCEDURE OPEN_TWO_CURSORS (EMPCURSOR OUT T_CURSOR,DEPTCURSOR OUT T_CURSOR)  IS    V_CURSOR1 T_CURSOR;    V_CURSOR2 T_CURSOR;  BEGIN    OPEN V_CURSOR1 FOR SELECT * FROM EMP;    OPEN V_CURSOR2 FOR SELECT * FROM DEPT;    EMPCURSOR  := V_CURSOR1;    DEPTCURSOR := V_CURSOR2;  END OPEN_TWO_CURSORS;END CURSPKG;/ORACLE提供REF CURSOR,通过该功能可以实现在程序间传递结果集的功能,利用REF CURSOR也可以实现BULK SQL,从而提高SQL性能。使用SCOTT用户的EMP表实现以下测试案例:SQL> DESC EMPNAME NULL? TYPE----------------------------------------- -------- ----------------------------EMPNO NOT NULL NUMBER(4)ENAME VARCHAR2(10)JOB VARCHAR2(9)MGR NUMBER(4)HIREDATE DATESAL NUMBER(7,2)COMM NUMBER(7,2)DEPTNO NUMBER(2)使用REF CURSOR获得结果集输出:SQL> SET SERVEROUTPUT ONSQL> DECLARE  TYPE MYTABLE IS TABLE OF EMP%ROWTYPE;    L_DATA MYTABLE;    L_REFC SYS_REFCURSOR;  BEGIN    OPEN L_REFC FOR SELECT EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO FROM EMP;    FETCH L_REFC BULK COLLECT INTO L_DATA;    CLOSE L_REFC;    FOR I IN 1 .. L_DATA.COUNT    LOOP      DBMS_OUTPUT.PUT_LINE (L_DATA (I).ENAME|| ' WAS HIRED SINCE '|| L_DATA (I).HIREDATE);    END LOOP;  END;/SMITH WAS HIRED SINCE 17-DEC-80ALLEN WAS HIRED SINCE 20-FEB-81WARD WAS HIRED SINCE 22-FEB-81JONES WAS HIRED SINCE 02-APR-81MARTIN WAS HIRED SINCE 28-SEP-81BLAKE WAS HIRED SINCE 01-MAY-81CLARK WAS HIRED SINCE 09-JUN-81SCOTT WAS HIRED SINCE 19-APR-87KING WAS HIRED SINCE 17-NOV-81TURNER WAS HIRED SINCE 08-SEP-81ADAMS WAS HIRED SINCE 23-MAY-87JAMES WAS HIRED SINCE 03-DEC-81FORD WAS HIRED SINCE 03-DEC-81MILLER WAS HIRED SINCE 23-JAN-82PL/SQL PROCEDURE SUCCESSFULLY COMPLETED.-THE END-

0 0
原创粉丝点击