Oracle07

1.写出plsql程序的结构 并说明每一部分的作用

2.写出 表名.字段名%type 的含义  以及  表名%rowtype 的含义

3.把下面的java 代码 翻译成 PLSQL的语法

  if(a > b){

  }else if(a > c){

  }else{

  }

4.使用while 循环  把一个变量的值 从 1 输出到  10 

5.写出PLSQL中的游标的使用步骤  并写出每一步的关键代码

------------------------------------------------------------------------------

1.定义一个游标  用来存放 s_emp 表中的  id  first_name  salary.

  提取这个游标的前两条数据  并打印。

declare

    cursor  empcursor is select  id,first_name name,salary from s_emp;

    var_emp  empcursor%rowtype;

begin

    open  empcursor;

    fetch  empcursor  into  var_emp;

    dbms_output.put_line(var_emp.id||':'||var_emp.name||':'||var_emp.salary);

    fetch  empcursor  into  var_emp;

    dbms_output.put_line(var_emp.id||':'||var_emp.name||':'||var_emp.salary);

    close  empcursor;

end;

/

2.如何提取出  游标中所有的数据?

  游标属性 

游标名 % found  当提取游标数据时  如果提取到了新数据 则这个属性返回TRUE。

    如果没有提取到新数据则返回FALSE。注意这个属性使用有两个前提 第一游标

    必须处于打开状态 否则就报非法游标的错,第二游标必须fetch 否则返回NULL。

游标名 % notfound  当提取游标数据时  如果提取到了新数据 则这个属性返回FALSE。

    如果没有提取到新数据则返回TRUE。注意这个属性使用有两个前提 第一游标

    必须处于打开状态 否则就报非法游标的错,第二游标必须fetch 否则返回NULL。 

使用简单循环 结合 notfound 属性遍历游标         

declare

    cursor  empcursor is select  id,first_name name,salary from s_emp;

    var_emp  empcursor%rowtype;

begin

    open  empcursor;

    loop

        fetch  empcursor  into  var_emp;

        -- 当提取不到新数据时 就结束循环

        exit  when  empcursor%notfound;

        dbms_output.put_line(var_emp.id||':'||var_emp.name||':'||var_emp.salary);

    end loop;

    close  empcursor;

end;

使用while循环 结合 found 属性  遍历上面的游标

  declare

    cursor  empcursor is select  id,first_name name,salary from s_emp;

    var_emp  empcursor%rowtype;

begin

    open  empcursor;

    fetch  empcursor  into  var_emp;

    while  empcursor%found loop

        dbms_output.put_line(var_emp.id||':'||var_emp.name||':'||var_emp.salary);

        fetch  empcursor  into  var_emp;

    end loop;

    close  empcursor;

end;

3. 游标的其它属性 (了解)

  游标名%isopen  判断游标是否打开  如果是打开状态则返回 TRUE  否则返回false 。

  注意 打开的游标不能再打开  关闭的游标 不能再关闭。

游标名%rowcount  游标指针偏移量  记录提取数据的指针偏移了多少

4.for 循环 遍历游标  ---  智能循环

  自动定义变量  自动打开游标    自动提取数据    自动关闭游标

declare

    cursor  empcursor is select  id,first_name name,salary from s_emp;

begin

    for var_emp in empcursor loop

        dbms_output.put_line(var_emp.id||':'||var_emp.name||':'||var_emp.salary);

    end loop;

end;

5.带参游标

  定义游标时 可以给游标设计参数  并且这些参数 可以在游标对应的select语句中使用

通过 我们打开游标时 传入实参就可以像正常游标一样去遍历了。

plsql 中参数不能加长度修饰  但是 可以使用 表名.字段名%type。

/*带参游标*/

  declare

    cursor  empcursor(var_id  number) is select  id,first_name name,

        salary from s_emp where id>var_id;

    var_emp  empcursor%rowtype;   

  begin

    open  empcursor(10);

    fetch  empcursor  into  var_emp;

    while  empcursor%found loop

        dbms_output.put_line(var_emp.id||':'||var_emp.name||':'||var_emp.salary);

        fetch  empcursor  into  var_emp;

    end loop;

    close  empcursor;

  end;

  / 

/*for +带参游标*/

  declare

    cursor  empcursor(var_id  number) is select  id,first_name name,

        salary from s_emp where id>var_id; 

  begin

    for var_emp in empcursor(15) loop

        dbms_output.put_line(var_emp.id||':'||var_emp.name||':'||var_emp.salary);

    end loop;

  end;

  / 

6.参考游标  ref cursor

6.1  动态sql的思路

  本质是游标对应的sql语句 是一条字符串

  语句是字符串  则 在程序运行的过程中 sql语句可以根据条件发生改变。

6.2  ref cursor 的使用 步骤

    a.定义一个参考游标 游标类型

        type  参考游标类型  is  ref cursor;

    b.使用这个类型定义一个游标变量

                  游标变量  参考游标类型;

    c.打开游标变量  传入对应的字符串   

        open  游标变量  for  sql字符串;

6.3 案例

/*if 拼接字符串 参考游标*/

    declare

        type  myrefcursor is  ref cursor;

        empcursor  myrefcursor;

        sqlstr    varchar2(200);

        id        s_emp.id%type:=10;

        salary    s_emp.salary%type:=2000;

        type  emptype is  record(

            id    s_emp.id%type,

            name  s_emp.first_name%type,

            salary s_emp.salary%type

        );

        var_emp  emptype;

    begin

        sqlstr:='select id,first_name name,salary from s_emp where 1=1 ';

        if id is not null  then

            sqlstr:=sqlstr||' and id<' || id;

        end  if;

        if  salary  is  not null then

            sqlstr:=sqlstr||' and salary < ' || salary;

        end  if;

        dbms_output.put_line(sqlstr);

        -- 打开游标变量时 传入对应的字符串

        open  empcursor  for  sqlstr;

        loop

            fetch  empcursor  into  var_emp;

            exit when  empcursor%notfound;

            dbms_output.put_line(var_emp.id||':'||var_emp.name||':'||var_emp.salary);

        end loop;

    end;

    /

  /*占位符参考游标*/

  declare

        type  myrefcursor is  ref cursor;

        empcursor  myrefcursor;

        sqlstr    varchar2(200);

        id        s_emp.id%type:=10;

        salary    s_emp.salary%type:=2000;

        type  emptype is  record(

            id    s_emp.id%type,

            name  s_emp.first_name%type,

            salary s_emp.salary%type

        );

        var_emp  emptype;

    begin

        sqlstr:='select id,first_name name,salary from s_emp where id < :b0 and salary < :b1';

        /* 当出现 :开头的占位符时  使用 using  传入实参 */

        open  empcursor  for  sqlstr using id,salary;

        loop

            fetch  empcursor  into  var_emp;

            exit when  empcursor%notfound;

            dbms_output.put_line(var_emp.id||':'||var_emp.name||':'||var_emp.salary);

        end loop;

    end;

    /

7.异常  (了解)

  7.1 异常的分类

      编译时异常    语法错误

      运行时异常    程序运行的过程中产生的错误


  7.2 举例

  declare

      var_name  s_emp.first_name%type;

  begin

      select  first_name  into var_name  from s_emp  where id=111;

      dbms_output.put_line(var_name);

  end;

  /

  一个程序执行  可能出现异常  也可能不出现异常

  7.3 如何处理

  异常处理 就是提前写好 程序的问题处理方案 

  declare

      var_name  s_emp.first_name%type;

  begin

      select  first_name  into var_name  from s_emp  where id=11;

      dbms_output.put_line(var_name);

  exception

      when  NO_DATA_FOUND  then

      dbms_output.put_line('no emp found'); 

      when  TOO_MANY_ROWS then

      dbms_output.put_line('select too many emp');

      when  others    then

      -- sqlcode 的意思是sql的状态码  sqlerrm  的意思是 sql error  message 简写

      dbms_output.put_line('have exception'||':'||SQLCODE||':'||SQLERRM); 

  end;

  / 

  8.过程  procedure  10*10*10

  8.1 什么是过程

      完成特定逻辑的一组代码的逻辑封装 。

  8.2 写一个plsql 的功能  定义两个整数变量  打印这两个变量的最大值

  declare

      var_x  number:=20;

      var_y  number:=50;

  begin

      if var_x < var_y  then

          dbms_output.put_line(var_y);

      else

          dbms_output.put_line(var_x);

      end  if;

  end;

  /

  这叫匿名块  直接可以执行  复用只能拷贝 这样后期维护和管理比较复杂

  8.3 把上面的匿名块 改造成 过程

  create  or  replace  procedure  getmax(var_x  number:=20,var_y number:=50)

  is

  begin

      if var_x < var_y  then

          dbms_output.put_line(var_y);

      else

          dbms_output.put_line(var_x);

      end  if;

  end;

  /

  create  or replace  procedure 过程名(参数  参数类型:=默认值,参数  参数类型:=默认值)

  is

      /* 这就是之前的申明区*/

  begin

  end;

  /

  8.4 如何调用

  call  过程名(参数);

  execute  过程名(参数); 

      这两种 了解一下    call 调用无参的也必须加()  execute 调用无参可以不加()

      在实际开发中 以直接调用为主

  begin

      /* 在匿名块中直接调用  匿名块可以调用过程  哪过程也可以调用过程 */

      getmax(111,222);

  end;

  / 

  8.5 写一个存储过程  设计两个整数参数  打印这两个参数的最小值  并使用匿名块验证功能。

  create  or  replace  procedure  getmin(var_x number:=0,var_y  number:=1)

  is

  begin

      if var_x < var_y  then

          dbms_output.put_line(var_x);

      else

          dbms_output.put_line(var_y);

      end if;   

  end;

  /

  begin

      getmin();

      getmin(11,9);

  end;

  /


  8.6 写一个存储过程  设计三个整数参数  打印这前两个参数的最小值  并且把前两个参数的和

      存入第三个参数中。


  static  void  getNum(int x){

      x=10000;

  }

  int main(){

      int  x=1;

      getNum(x);

      x

  }

  static  void  getString(String  x){

      x="abc";

  }

  int main(){

      String  x=new  String("a");

      getString(x);

      x

  }

  static  void  getString(StringBuffer  x){

      x.append("abc");

  }

  int main(){

      StringBuffer  x = new  StringBuffer("a");

      getString(x);

      x

  }


  plsql中默认的参数 是in 参数  只能读不能写

      如果希望存储过程带回值  则使用out 参数


  create  or  replace  procedure getmin_and_sum(var_x in number,var_y number,

  var_z out number)

  is

  begin

      dbms_output.put_line('var_z='||var_z);

      if var_x < var_y  then

          dbms_output.put_line(var_x);

      else

          dbms_output.put_line(var_y);

      end if;

      var_z:=var_x+var_y;

  end;

  /


  注意:调用 带有out 参数的过程时,out模式的参数 必须是变量

  declare

      var_z  number:=100;

  begin

      getmin_and_sum(1,9,var_z);

      dbms_output.put_line(var_z);

  end;

  /

  参数的模式:

    in  默认的  只负责给存储过程传入值

    out  只负责给存储过程传出值

    in out  既能给存储过程传入值 又能传出值


    写一个存储过程  设计二个整数参数  打印这两个参数的最小值  并且把前两个参数的和

      存入第二个参数中。

  create  or  replace  procedure getmin_and_sum(var_x in number:=1,

      var_y  in out number)

  is

  begin

      if var_x < var_y  then

          dbms_output.put_line(var_x);

      else

          dbms_output.put_line(var_y);

      end if;

      var_y:=var_x+var_y;

  end;

  /   

  8.7 如何调用一个大家不熟悉的存储过程

  查看存储过程  desc  过程名;

  desc  getmin_and_sum;

  a.获取参数的名字

  b.参数的类型

  c.参数的模式 如果有out 修饰 则必须是变量

  d.参数是否有默认值    要获取具体的默认值  测试 查看公司文档  查看源代码

    select text  from user_source  where name='GETMIN_AND_SUM';


    参数的位置赋值

  declare

      var_y  number:=10;

  begin

      getmin_and_sum(1,var_y);

      dbms_output.put_line(var_y);

  end;

  /

  参数的名字赋值  可以改变赋值的顺序  参数名=>参数的值  (了解)

  declare

      var_y  number:=9;

  begin

      getmin_and_sum(var_y=>var_y,var_x=>1);

      dbms_output.put_line(var_y);

  end;

  /

  8.8 设计一个存储过程  可以传入一个参数 n  这个参数代表从1 加到的数

  还有一个参数可以存储 前n项的 和。  调用这个存储过程验证功能。

如 n = 10  1+2+3+4+5+6+7+8+9+10=55

create  or  replace  procedure getNumN(n in number,var_sum  out number)

is

begin

    var_sum:=0;

    for i in 1..n loop

        var_sum:=var_sum+i;

    end loop;

end;

/


declare

    var_sum  number:=100;

begin

    getNumN(100,var_sum);

    dbms_output.put_line('var_sum='||var_sum);

end;

/


  declare

    var_sum  number:=100;

begin

    getNumN(var_sum=>var_sum,n=>100);

    dbms_output.put_line('var_sum='||var_sum);

end;

9.函数

  9.1 过程和函数的区别

      a.第一关键字不同  过程是 procedure  函数是 function

      b.函数有返回值类型 和 返回值  而过程没有

      c.调用方式不同  过程可以直接调用  函数必须组成表达式才能调用

  9.2 语法

      create  or replace  function  函数名(参数名  参数类型:=值,参数名  参数类型:=值)

      return  返回值类型 

      is

          -- 定义类型  定义变量

      begin

          if  条件  then

              return  值;

          end if;   

      end;

      /

  9.3 设计一个plsql 函数 有两个整数参数  返回两个参数的最大值

      drop  procedure    getmax;

      create or replace  function  getmax(var_x  in number,var_y number)

        return  number 

        is

        begin

            if  var_x < var_y then

                return  var_y;

            end if;

                return  var_x;     

        end;

        /


    这只是 测试

    select  getmax(1,100) from dual;       

  真正的调用 有匿名块 或者 有名块调用

  begin

      dbms_output.put_line(getmax(1,999));

      if getmax(1,999) > 900 then

          dbms_output.put_line('ggggg');

      end if;

  end;

  /


  9.4 设计一个函数 有两个整数参数  返回参数的最大值  并且把两个参数的和存入第二个参数中

  调用这个函数 验证函数的功能。

你可能感兴趣的:(Oracle07)