`
Luob.
  • 浏览: 1575039 次
  • 来自: 上海
社区版块
存档分类
最新评论

Oralce 开发包 和 游标

阅读更多

--________________________________开发包______________________________________________________
 
 --包 :组合逻辑相关的PL/SQL 类型(table 类型,record 类型,游标和游标变量, 过程和函数) 提高性能,隐藏信息(私有),子程序重载
 
 --1.创建包 (包:由包规范 和包体 组成, 创建包是要首先创建包规范 ,然后 包体)  实际上包规范是包与应用程序之间的接口
  
   --A 首先 创建包规范 create package

  --语法:
   create [or replace] package package_name   --package_name 指定包名
   is|AS                                           --用于定义共有组件
   public type end item declareations
   subprogram specifications 
   end package_name;
   
   --示例
   create or replace package emp_package   --定义emp_package
   As
       g_deptno number(3):=30;    --定义公有变量
       procedure pro_add_employee   --定义公有的 过程
       (
         param_empno number,
         param_ename varchar2,
         param_sal number,
         param_deptno number:=g_deptno
       )
        --定义公有的函数fun_get_sal;
       function fun_get_sal(param_empnno number)return number;
       
       --***过程和函数 都没有给出具体的实现  所以 公有的函数和过程 只有在创建了包体后才能调用
   END emp_package;
 
 
   --B: 创包体; create package body (实现包规范中定义的过程和函数) 可以定义私有的组件(变量,常量,过程, 函数)只能在包体中使用
   
      --语法
        create [or replace] package body package_name  --package_name用于指定包名 和包规范名称一样
        iS|AS                                          --定义自由组件的开始 并实现公有的函数和过程
            private type and item declarations subprogram bodies
        end package_name;
        
      --示例 1
       create or replace package body emp_package  --创建包体名
       As
       
       --定义私有的 函数
         function fun_vallidate_dept(param_deptno number)
         return boolean
         as
            v_temp number;
         begin
           select 1 into v_temp from dept where deptno=param_deptno;
           return true;
         Exception
           when no_data_found then
           return false;
         END;
         
         --实现 包规范中的 pro_add_employee 过程
         procedure pro_add_employee
         (
            param_name number,
            param_ename varchar2,
            param_sal number,
            param_deptno number:=g_deptno
            
         )
         AS
         begin
           if fun_vallidate_dept(param_deptno) then   --调用了同一包中的 组件  fun_vallidate_dept
              insert into emp(empno,ename,sal,deptno) values(param_empno,param_ename,param_sal,param_deptno);
           else
              raise_application_error(-2000,'不存在该部门!');
           end if;
          Exception
           when DUP_VAL_On_index then
              raise_application_error(-2002,'该员工编号已经存在!');
          end;
          
          --实现公有函数fun_get_sal
          function fun_get_sal(param_empno number) return number
          as
            v_sal emp.sal%type;
          begin
            select sal into v_sal from emp where empno=param_empno;
            return v_sal;
          Exception
             wher no_data_found then
                raise_application_error(-2000,'该员工不存在!');
          end;
        end emp_package;

--在同一包中调用
    直接调用(如上示例 的 pro_pro_add_employee): fun_vallidate_dept

--调用包的公用变量
   begin 
       emp_package.g_deptno:=20;
   end;
--调用包的公有过程
   begin
       emp_package.g_deptno:=20;
       emp_package.proc_add_employee(8888,'chen',3000);
       emp_package.proc_add_employee(8889,'yaun',3000,30);
   end;
--调用包的公用函数  (要定义变量来接受返回值)
  declare
    v_sal emp.sal%type;
  begin
    v_sal:=emp_package.fun_get_sal(7788);
    DBMS_OUTPUT.put_Line('员工7788的工资是:'||V-sal);
  end;
--不同用户调用包的公用组件  (要有权限)
  grant execute on emp_package to hr;
  conn hr/hr@oracl;
  
  begin
     scott.emp_package.pro_add_employee(2010,'tiger',2000);
  end;
  
--查看包的源代码
  conn scott/tiger@orcl
  
  select text from user_source where name='emp_package' and type='package';

--删除包
  drop package emp_package;






--__________________________________游标___________________________________________---

--游标分为   1.隐含游标:(处理 select into 和DML语句)
           --2.显示游标: (处理select 语句返回多行数据)
  
  
--显示游标 (定义游标declare,打开游标open,提取数据fethch,关闭游标close)
   
    --1.定有游标 (在使用显示游标的时候,必须首先在定义部分定义游标,用于定义游标所对应的select语句)
       --语法
        cursor cursor_name is select_statement;  --cursor_name 游标的名称,select_statement:指定游标对应的select 语句
        
   --2.打开游标  (打开游标的时候,oracle 会执行游标所对应的select 语句,将select语句的结果暂时放在结果集中)
         open cursor_name; --cursor_name :必须在定义部分定义已经定义了的游标
         
   --3.提取数据  (oracle 9i之前 fetch 每次只能提取一行数据 在oracle 9i 之后 通过fetch ....bulk collect into 语句一次可提取多行数据)
          fetch cusor_name into variable1,variable2,....;    --variavle:用于指定接受游标数据的变量
          --或者
          fetch cusor_name bulk collect into colllec1,collect2,.....;   --collect:用于指定接受游标结果的集合变量
   --4.关闭游标
         close cusor_name;

--显示游标的属性  (返回显示游标的执行信息 包括 %isopen,%found,%notfound,%rowcount)
   --1.isopen  (判断游标是否已经打开)
       if cusor_name %isopen then
            执行语句
       else 
          open cusor_name;
       end if;
   --2.%found (检测是否从数据集中提取到数据,提取到 返回true)
      LOOP
         fetch cusor_name into var1,var2;
             if cusro_name%fount then
                  执行语句;
             else 
                exit;
             end if;
      ENd LOOP;
   --3.%notfound (检测是否从数据集中提取到数据,没有提取到 返回true)
   
      LOOP
          fetch cusor_name into var1,var2;
          exit when cusor_name%notfound;
          ....
      END LOOP;
   --4.%rowcount  (返回到当前行为止,已经提取到的世纪行数)
      LOOP
         fetch cusor_name into var1,var2;
         if cusor_name%rowcount>n then   --执行提取数据的行数大于n时候,要执行的语句
               .....
         END if;
         exit 
           when cusor_name%notfound;
      END LOOP;
 
--显示游标的使用示例
   --1.在显示游标中使用 fetch  ....into ..语句  (fetch ...into.. 每次只能提取一行,要处理结果集中多行数据,必须使用循环语句);
      declare
         cursor emp_cursor is select ename,sal from emp where deptno=30;
         v_name emp.ename%type;
         v_sal emp.sal%type;
       begin
         open emp_cursor;  
         Loop 
            fetch emp_cursor into v_name,v_sal;
            exit when emp_cursor%notfound;
            DBMS_OUTPUT.put_line(v_name||' '||v_sal);
         end LOOP;
         close emp_cursor;
       end;
       
    --2.在显示游标中,使用fetch...bulk collect into提取所有的数据
      declare
        cursor emp_cursor is select ename,sal from emp where deptno=10;
        type emp_record is record
        (
           ename emp.ename%type,
           sal emp.sal%type
        );
        type ename_table_type is table of emp_record;
        v_name_table ename_table_type;
        begin
          open emp_cursor;
          fetch emp_cursor bulk collect into v_ename_table;
          close emp_cursor;
          for i in v_ename_table.first..v_emp_table.last llllllllllllllllllll.
             LOOP  
                   DBMS_OUTPUT.put_line(v_ename_table(i).ename||'    '||v_ename_table(i).sal);
             END loop;
        END;
     --3.在游标中使用属性
       cursor emp_cursor is select ename from emp where deptno=10;
       type ename_table_type is table  of varchar2(10);
       v_ename_table ename_table_type;
       begin
         if not emp_cursor%isopen then
            open emp_cursor;
         end if;
         fetch emp_cursor bulk collect into v_name_table;
           DBMS_OUTPUT.put_line('提取的总行数'||emp_cursor%rowcount);
           close emp_corsor;
       end; 
       
       --4.基于游标定义记录变量 (%rowtype可以基于表和视图定义记录变量,还可以基于游标定义记录变量)
       declare
         cursor emp_cursor is select ename,sal from emp where deptno=10;
         emp_record emp_cursor%rowtype;
         begin
             open emp_cursor;
             LOOP
              fetch emp_cursor into emp_record;
              exit when emp_cursor&notfound;
              DBMS_OUTPUT.put_line(emp_record.ename||'  '||emp_record_sal);
             end LOOP;
         end;
       
       --5.参数游标 (使用不同参数多次打开游标可以生成不同的结果集)
          cursor cursor_name(parameter_name datatype) is select_statement;
          --示例
            declare            --下面 定义了带参数的游标  指定数据类型不能指定长度
              cursor emp_cursor(param_dept number) is select ename,sal from emp where deptno=param_dept;
              emp_record emp_cursor%rowtype;
            begin
               open emp_cursor(10);    --打开游标时候 传入参数 (10) 表示查询 部门编号为10 的所有员工的姓名和工资   
               loop
                fetch emp_cursor into emp_record;
                exit when emp_cursor%notfound;
                DBMS_OUTPUT.put_line(emp_cursor.ename||'     '||emp_cursor.sal);
               end loop;
               close emp_cursor;
            end;
            
         --6.是有游标更新或删除数据  (在定义游标时候 带有for update)
            --语法
              cursor cursor_name(param_naem datatype) is select_statement for update [nowalt];
            --更新数据
              declare
                cursor emp_cursor is select ename,sal from emp for update;
                v_emp_row emp_cursor%rowtype;
                v_update_emp_count number(2):=0;
              begin
                open emp_cursor;
                LOOP
                  fetch emp_cursor into v_emp_row;
                  exit when emp_cursor%notfound;
                  if v_emp_row.sal<2000 then
                    update emp set sal=sal+100 where current of emp_cursor;
                    v_update_emp_count:=v_update_emp_count+1;
                  end if;
                 end LOOP;
                 dbms_output.put_line('共有'||v_update_emp_count||'名员工被更新了!');
                 close  emp_cursor;
               end;
               
             --使用游标删除数据
               declare
                 cursor emp_cursor is select deptno form emp for update;
                 v_emp_row emp_cursor%rowtype;
                 v_update_emp_count mumber(2):=0;
                 begin
                    open emp_cursor;
                    loop
                      fetch emp_cursor into v_emp_row;
                      exit when emp_cursor%notfound;
                      if v_emp_row.deptno=30 then
                         delete emp where current of emp_currsor;
                         v_update_emp_count:=v_update_emp_count+1;
                      end if;
                    end loop;
                   DBMS_OUTPUT.put_Line('共有'||v_update_emp_count||'名雇员删除了!');
                   close emp_cursor;
                 end;
                  

    declare  
     cursor emp_cursor is 
    select ename,sal from emp form update nowalt;
    v_emp_row emp_sursor%RowType;
     u_upate_emp_count number(2):=0;
    begin
     open emp_cursor;
     loop
        fetch emp_cursor into v_emp_row;
        exit when emp_cursor%notfound;
       if v_emp_row.sal<2000 then
          update emp set sal=sal+100 where current of emp_cursor;
          v_updae_emp_count:=v_update_emp_count+1;
          end if
     end loop;
       dbms_output.put_line('共有'|| _update_emp_count||‘员工被更新了 !’);
    close emp_cursor;
end 



--游标for 循环


declare 

    --定义游标
    cursor emp_cursor is select ename,sal form emp;
   begin
        for emp_row in emp_cursor loop
          dbms_output.put_line('第'||emp_cursor%RowCount ||'个员工:'||emp_row.ename);
        end loop;

  end;


在for 游标中直接使用 子查询
     begin   
         for   emp_row int (select ename,sal form emp) loop
                ebms_output.put_line(emp_row.ename);
          end loop;

     end;   

--使用游标变量
   定义ref cursor 类型 和游标变量
        
    type ref_type_name is ref cursor;
    cursor_variable  ref_type_name;

--游标变量使用
    依次显示部门编号为30 的所有员工的 说明使用游标变量的方法 
     declare
        TYPE emp_cursor_type is REF CURSOR;
         
        emp_cursor emp_cursor_type;
        emp_row emp%ROWTYPE;
     begin
       open emp_cursor for
         select * from em where deptno=30;
         loop
           fetch emp_cursor into emp_row;
           exit when emp_cursor%notfound;
           dbms_output.put_line('第'||emp_cursor%RowCount||'个员工:'||emp_row.ename);
         end loop;
        close emp_cursor;
     end;


---使用游标变量开发返回结果集的子程序
   create or replace procedure proc_getEmpsByDeptNO
   (
       param_deptno number,
       param_resultset out  SYS_REFCURSOR

    )
      as
     begin
        open param_resultset for 
             select ename,sal from emp where deptno=param_deptNo;
     end;



    declare
       TYPE emp_record_type is record
	(
		ename varchar2(20),
  		sal number(7,2)	
	) ;   
     v_emp_rows SYS_REFCURSOR;
     v_deptno number(2):=30;
     v_emp_row emp_record_type;

  begin
     pro_getEmpByDeptno(v_deptno,v_emp_rows);
  LOOP
    fetch v_emp_Row into v_emp_row;
    exit when v_emp_rows%NOTFOUND;
     DBMS.output.put_line('第'||v_emp_rows%rowcount||‘员工 名称’||v_emp_row.ename||'工资'||v_emp.row.sal);
  end loop;
  close v_emp_rows;

end;


--开发返回结果集的函数
  create or replace function fun_getEmpByDateYear
(
	param_hireDareYear number

)
return sys_REFCURSOR
as
  param_resultset sys_REFCUSOR;
begin
    open param_resultset for
      select ename,sal from emp  where EXTRACT(Year from hrdare )=param_hirdDateYear;
   return param_resultset;
end


declare
    TYPE emp_record_Type is record
	(
		ename varchar2(20);
    		sal number(7,1)
	);
       v_emp_rows SYS_REFCURSOR;
       v_hireDateYear number(4):=1981;
       v_emp_row emp_record_type;
       begin
          v_emp_rows:=fun_getEmpsByHireDateYear(v_hireDateYear);
         loop
           fetch v_emp_rows into v_emp_row;
           exit when v_emp_rows%NOTFOUND;
          DBMS.output.put_line('第'||v_emp_rows%rowcount ||'个员工的名称:'||v_emp_row.name||'工资'||v_emp_row.sal);
        end loop;
      close v_emp_rows;
 end;


--隐含游标的属性 (SQL%FOUND   SQL%NOTFOUND   SQL%rowcount SQL%isopen)
    
     1 :SQL%FOUND
       decare 
          v_empno number(4):=7788;
       begin  update emp set empno=v_empno where empno=v_empno;
       if  sql%fount then
              dbms_out.put.put_line('存在该员工');
       else
             dbms_output.put_line('不存在该员工');
     end if;
  end ;

   2: SQL%NOTFOUND  与  SQL%FOUND  相反


   3:  declare
            v_deptno number(2):=20;
            v_rows_count number;
            begin updare emp set sal =sal+100 where deptno=v_deptno;
             v_row_count:=Sql%rowCount;
       if v_rows_count =0 then
            dbms_output.put_line('没有员工被更新!');
       else
            dbms_output.put_line('共有:'||_rows_count||'个员工被更新了!');
       end  if;
end;

分享到:
评论

相关推荐

    Oracle数据库实验-PLSQL游标、过程、函数、包的使用[文].pdf

    Oracle数据库实验-PLSQL游标、过程、函数、包的使用[文].pdf

    Oracle开发基础

    Oracle开发基础,一些基本代码的整理,自创文件,包含游标、记录、集合等

    oracle存储过程和函数PPT

    主要介绍Oracle数据库开发技术,包括存储过程、函数、游标及plsql的教程。

    Oracle包应用详解.doc

    (1)包是一种数据库对象,将逻辑上相关的PL/SQL类型、对象和子程序组合成一个更大的单位,是一组相关过程、函数、变量、常量和游标等PL/SQL程序设计元素的组合,它具有面向对象程序设计语言的特点,是对这些PL/SQL ...

    Oracle 11g SQL和PL SQL从入门到精通 pdf格式电子书 下载(一)

     除了为读者提供编写sql语句和开发pl/sql块的方法外,本书还为应用开发人员提供了一些常用的pl/sql系统包。通过使用这些pl/sql系统包,应用开发人员可以开发出功能更强大的数据库应用程序。本书不仅适合sql和pl/sql...

    Oracle 11g SQL和PL SQL从入门到精通 pdf格式电子书 下载(二)

     本书是专门为oracle应用开发人员提供的sql和pl/sql编程指南。通过学习本书,读者不仅可以掌握oracle常用工具oracle universal installer、net comfiguration assistant、sql developer、sql*plus的作用及使用方法...

    大数据Oracle理论+SQL+面试问题汇总+BI理论

    本课程适应从事大数据行业开发人员或数据库开发人员以及BI开发人员,其中包含有ORACLE的理论基础知识,OracleSQL语句详细讲解、面试问题汇总、BI理论知识。汇总了Oracle在开发中常用到的各种函数如分析函数、开窗...

    Oracle11g从入门到精通2

    从实际角度出发,系统地介绍了数据库和Oracle的相关概念和原理、Oracle的数据库管理(如安装与启动,用户权限、备份与恢复等),以及Oracle的应用开发基础,并通过两个完整案例来介绍基于Java开发包和Oracle数据库...

    Oracle 11g SQL和PL SQL从入门到精通part2 pdf格式电子书 下载(二)

     除了为读者提供编写sql语句和开发pl/sql块的方法外,本书还为应用开发人员提供了一些常用的pl/sql系统包。通过使用这些pl/sql系统包,应用开发人员可以开发出功能更强大的数据库应用程序。本书不仅适合sql和pl/sql...

    Oracle 11g SQL和PL SQL从入门到精通〖送源代码〗

    本书是专门为Oracle应用开发人员提供的SQL和PL/SQL编程指南。通过学习本书,读者不仅可以掌握Oracle常用工具Oracle Universal Installer、Net Comfiguration Assistant、SQL Developer、SQL*Plus的作用及使用方法,...

    Oracle 11g SQL和PL SQL从入门到精通.part1

     本书是专门为oracle应用开发人员提供的sql和pl/sql编程指南。通过学习本书,读者不仅可以掌握oracle常用工具oracle universal installer、net comfiguration assistant、sql developer、sql*plus的作用及使用方法...

    Oracle从基础到熟练(太实用了)

    ④:使用游标的好处和坏处 十.子程序[proc,udf],自主事务处理和程序包 ①:存储过程 ②:函数 ③:自主事务处理 ④:包规范|包主体 十一.触发器|内置包 ①:触发器类型 ②:触发器原理 ③:new和old 两个行类型变量 ...

    Oracle11g从入门到精通

    从实际角度出发,系统地介绍了数据库和Oracle的相关概念和原理、Oracle的数据库管理(如安装与启动,用户权限、备份与恢复等),以及Oracle的应用开发基础,并通过两个完整案例来介绍基于Java开发包和Oracle数据库...

    21天学通Oracle

    第一篇 Oracle管理配置 第1章 Oracle安装配置(教学视频:10分钟) 23 1.1 Oracle简介 23 1.1.1 数据库术语 23 1.1.2 主流数据库简介 24 ...第23章 Oracle在C#开发中的应用(教学视频:12分钟) 391

    学生成绩管理系统Oracle全部SQL语句.txt

    3、要求使用sqlplus,pl/sql或developer建立存储过程,触发器和程序包等代码,其中要求用到游标,异常,各种语句等对表中数据进行处理; 4、使用自己熟悉的开发语言,加入界面,连接数据库; 5、报告要有操作截图...

    ORACLE11G宝典.rar 是光盘里面的内容,书太厚咧没法影印啊

     《Oracle11g宝典》是Oracle数据库管理员、安全管理员、网络管理员、应用开发人员的参考指南,还是Oracle技术支持和培训机构、Oracle学习班、高等院校计算机专业数据库课程的参考教材和上机指导教材。每类人员都...

    Oracle Database 11g初学者指南--详细书签版

    在过去的14年中,他与IanAbramson和MichaelCorey为OraclePress合著了一系列图书.Abbey在国际Oracle用户团体非常活跃,经常出席COLLABORATE、OraclecOpenWorld和区域性用户组会议.  Michael J.Corey是Ntirety...

    Oracle 10g 开发与管理

    第八讲 过程、函数和程序包 72 8.1存储过程(procedure) 72 1.创建 72 2.调用存储过程 72 3.修改(替换同名的存储过程) 73 4.参数 73 (1)In 参数:向过程传入一个值 73 (2)Out参数: 73 (3)In Out参数: 74 ...

Global site tag (gtag.js) - Google Analytics