-- 存储过程:过程是用于完成特定任务的子程序(代码的集合)

/*

   子程序的优点:1.模块化,将程序分解为逻辑模块;

                 2.可重用性,可以被任意数目的程序调用;

                 3,可维护性,简化维护操作;

                 4.安全性:通过设置权限,是数据

*/

-- 存储过程1,打印HelloWorld

create or replace procedure my_pro

is    -- 用于声明一些变量,可以用as,在oracle中不能省略,在Mysql中不能有

  v_string varchar2(20) := 'helloworld!';

begin

  dbms_output.put_line(v_string);

end;

-- 调用1

begin

  my_pro; -- 这种方式调用无参的存储过程,括号可以省略

  my_pro();

end;

--调用2

call my_pro(); --无参的也必须带括号

--调用3,在command中输入 set serveroutput on  execute my_pro();

 

-- 存储过程2,带参数的,默认是输入参数

create or replace procedure my_pro2(v_sal  number) -- 参数,要制定类型,varchar不能指定长度

is

   v_sql varchar2(200);

   v_emp emp%rowtype;

begin

  v_sql := 'select * from emp where sal =: s';

  execute immediate v_sql into v_emp

  using v_sal;

  dbms_output.put_line(v_emp.ename);

  exception

    when no_data_found then

      dbms_output.put_line('没有找到!');

end;

 

select * from emp;

call my_pro2(820);

 

-- 存储过程3,带参数,输入(in)和输出(out)参数,关键字:in out,不写默认是in

create or replace procedure my_pro3(v_sal number, v_name out emp.ename%type) --out

is

  v_sql varchar2(200);

begin

  v_sql := 'select ename from emp where sal =: s';

  execute immediate v_sql into v_name

  using v_sal;

end;

-- 调用

declare

  v_sal number := '&输入薪水:';

  v_name varchar2(20);

begin

  my_pro3(v_sal,v_name);

  dbms_output.put_line(v_name);

end;

--存储过程4,输入输出类型,in out,交换两个数

create or replace procedure swap(v_num1 in out number, v_num2 in out number)-- in out 顺序不能颠倒

as

  v_temp number;

begin

  v_temp := v_num1;

  v_num1 := v_num2;

  v_num2 := v_temp;

end;

-- 调用

declare

  v_num1 number := '&num1';

  v_num2 number := '&num2';

begin

  dbms_output.put_line('交换前:num1 = '||v_num1||'-----num2 = '||v_num2);

  swap(v_num1,v_num2);

  dbms_output.put_line('交换后:num1 = '||v_num1||'-----num2 = '||v_num2);

end;

 

--存储过程5,计算总页数和总记录数

create or replace procedure countPageAndRecords

       (tableName varchar2, pageSize number,totalRecord out number,totalPage out number)

as

  v_sql varchar2(200);

begin

  v_sql := 'select count(*) from '||tableName;

  execute immediate v_sql into totalRecord;

  totalPage := ceil(totalRecord/pageSize);

  -- 计算方式二

  if mod(totalRecord,pageSize) = 0 then

    totalPage := totalRecord/pageSize;

  else

    totalPage := floor(totalRecord/pageSize)+1;

  end if;

end;

--测试

declare

  tableName varchar2(50) := '&表名:';

  pageSize number := '&分页单位:';

  totalRecord number;

  totalPage number;

begin

  countPageAndRecords(tableName,pageSize,totalRecord,totalPage);

  dbms_output.put_line('总数为:'||totalRecord);

  dbms_output.put_line('总页数为:'||totalPage);

end;