oracle数据库的存储过程PROCEDURE与函数FUNCTION示例

程序结构
=============================================================
例题1:
取出s_emp表(参见oracle默认数据库test中的相关表)中的记录用变量接收并输出
s_emp //变量要和s_emp表中的数据类型相匹配
___________________________________________________________
DECLARE
  v_id NUMBER(7);
  v_fname VARCHAR2(25);
  v_salary NUMBER(11,2);
BEGIN
  select id,first_name,salary
  into v_id,v_fname,v_salary
  from s_emp
  where id =1;     //唯一确定一条数据,否则会出错
  DBMS_OUTPUT.PUT_LINE(v_id||' '||v_fname||' '||v_sarary);
END;
___________________________________________________________

如果把s_emp表中的first_name字段的长度改为VARCHAR2(30)
那么也要把v_fname改成VARCHAR2(30)
解决方法:
v_fname VARCHAR2(25);--->
v_fname s_emp.first_name%TYPE;

v_id NUMBER(7);--->
v_id s_emp.id%TYPE;

v_salary NUMBER(11,2);--->
v_salary s_emp.salary%TYPE;

==============================================================
例题2
_______________________________________________________
DECLARE
  TYPE t_emp IS RECORD(
  id s_emp.id%TYPE,
  fname s_emp.first_name%TYPE,
  salary s_emp.salary%TYPE
  );
  v_emp t_emp;
BEGIN
  select id,first_name,salary
  into v_emp.id,v_emp.fname,v_emp.salary   <=>into v_emp
  from s_emp
  where id =1;  
  DBMS_OUTPUT.PUT_LINE(v_emp.id||' '||v_emp.fname
  ||' '||v_emp.sarary);
END;
_______________________________________________________
into v_emp.id,v_emp.fname,v_emp.salary<=>into v_emp
into简化前提
RECORD定义的变量顺序和select查询时的顺序必须相同

=============================================================

例题3
_______________________________________________________
DECLARE
  TYPE t_emp IS RECORD(
  id s_emp.id%TYPE,
  fname s_emp.first_name%TYPE,
  salary s_emp.salary%TYPE
  );

  v_emp t_emp;
 
  v_emp2 t_emp;

BEGIN
  select id,first_name,salary
  into v_emp
  from s_emp
  where id =1;  

/*v_emp2.id := v_emp.id;
  v_emp2.fname := v_emp.fname;
  v_emp2.salary := v_emp.salary;*/
  v_emp2 := v_emp;

  DBMS_OUTPUT.PUT_LINE(v_emp.id||' '||v_emp.fname
  ||' '||v_emp.sarary);
END;
_______________________________________________________
  (v_emp2.id := v_emp.id;
  v_emp2.fname := v_emp.fname;
  v_emp2.salary := v_emp.salary;)
  <=>
  (v_emp2 := v_emp;)

==============================================================
例题4
_____________________________________________________
DECLARE
  TYPE t_emp IS RECORD(
  id s_emp.id%TYPE,
  fname s_emp.first_name%TYPE,
  salary s_emp.salary%TYPE
  );

  TYPE t_emp2 IS RECORD(
  id s_emp.id%TYPE,
  fname s_emp.first_name%TYPE,
  salary s_emp.salary%TYPE
  );

  v_emp t_emp;
 
  v_emp2 t_emp2;

BEGIN
  select id,first_name,salary
  into v_emp.id,v_emp.fname,v_emp.salary   <=>into v_emp
  from s_emp
  where id =1;  
  v_emp2 := v_emp;                 --error类型不一致
  DBMS_OUTPUT.PUT_LINE(v_emp.id||' '||v_emp.fname
  ||' '||v_emp.sarary);
END;
____________________________________________________________

===============================================================
例题5:
1>__________________________________________________________
DECLARE
  TYPE t_emp IS RECORD(
  id s_emp.id%TYPE,
  lname s_emp.last_name%TYPE,
  fname s_emp.first_name%TYPE,  
  uid s_emp.userid%TYPE
  .....
  salary s_emp.salary%TYPE,
  );

  v_emp t_emp;

BEGIN
  select *
  into v_emp
  from s_emp
  where id =1;  
  DBMS_OUTPUT.PUT_LINE(v_emp.id||' '||v_emp.fname
  ||' '||v_emp.sarary);
END;
_________________________________________________________

<1>vs<2>
  TYPE t_emp IS RECORD(
  id s_emp.id%TYPE,
  lname s_emp.last_name%TYPE,
  fname s_emp.first_name%TYPE,  <=>v_emp s_emp%ROWTYPE;
  uid s_emp.userid%TYPE
  .....
  salary s_emp.salary%TYPE,
  );

  v_emp t_emp;


2>________________________________________________________
DECLARE
  v_emp s_emp%ROWTYPE;    //v_emp和表s_emp始终有相同的结构

BEGIN
  select *
  into v_emp
  from s_emp
  where id =1;  
  DBMS_OUTPUT.PUT_LINE(v_emp.id||' '||v_emp.first_name
  ||' '||v_emp.sarary);
END;

输出时用的字段名就是s_emp表中的字段名
__________________________________________________________

============================================================

table类型
BINARY_INTEGER的范围(-2147483647<-->+2147483647)
底层是用二叉数实现的.插入时排序
_________________________________________________________
DECLARE
  TYPE t_emp IS TABLE OF s_emp%ROWTYPE INDEX BY BINARY_INTEGER;

  v_emp t_emp;
BEGIN
  SELECT *
     INTO v_emp(100)  --索引的位置没有太多要求v_emp(-100)
   FROM s_emp
 WHERE id=1;
 
 SELECT *
   INTO v_emp(2000)
  FROM s_emp
 WHERE id=2;
 
 DBMS_OUTPUT.PUT_LINE(v_emp(2000).id||' '||
 v_emp(2000).first_name);
END;
_________________________________________________________

=============================================================

练习:
从s_emp表中查id,first_name,dept_id,salary
1>RECORD
2>ROWTYPE
3>找出信息后保存到TABLE类型变量中
lhj_test1.sql
<1>
DECLARE
  TYPE v_emp IS RECORD(
    id s_emp.id%TYPE,
    fname s_emp.first_name%TYPE,
    did s_emp.dept_id%TYPE,
    salary s_emp.salary%TYPE
  );
  t_emp v_emp;
BEGIN
  SELECT id,first_name,dept_id,salary
  INTO t_emp
  FROM s_emp
  WHERE id=1;
 DBMS_OUTPUT.PUT_LINE(t_emp.id||' '||t_emp.fname||
 ' '||t_emp.did||' '||t_emp.salary);
END;

<2>
DECLARE
  t_emp s_emp%ROWTYPE;
BEGIN
  SELECT *
  INTO t_emp
  FROM s_emp
  WHERE id=1;
 DBMS_OUTPUT.PUT_LINE(t_emp.id||' '||t_emp.first_name||
 ' '||t_emp.dept_id||' '||t_emp.salary);
END;

<3>
DECLARE
 TYPE t_emp IS TABLE OF s_emp%ROWTYPE INDEX BY BINARY_INTEGER;

 v_emp temp;

BEGIN
 SELECT *
  INTO v_emp(1)
  FROM s_emp
  WHERE id=1;
 DBMS_OUTPUT.PUT_LINE(v_emp(1).id||' '||v_emp(1).first_name||
 ' '||v_emp(1).dept_id||' '||v_emp(1).salary);

END;
==============================================================
变量的作用域与可见性
1>
<<Outer>>--标号
DECLARE
  v_Num NUMBER := 100;
BEGIN
  v_Num := 1;
 
  DECLARE
   v_Str VARCHAR2(20) := 'hello';
   v_Num NUMBER := 200;
  BEGIN
   DBMS_OUTPUT.PUT_LINE('v_Str = ' || v_Str);
   DBMS_OUTPUT.PUT_LINE('v_Num = ' || v_Num);  --v_Num=200
 --DBMS_OUTPUT.PUT_LINE('v_Num = ' || Outer.v_Num);
  END;

 --DBMS_OUTPUT.PUT_LINE('v_Str = ' || v_Str);   --error
END;

2>
DECLARE
  v_Num NUMBER := 100;
BEGIN
  v_Num1 := 1;
 
  DECLARE
   v_Str VARCHAR2(20) := 'hello';
   v_Num2 NUMBER := 200;
  BEGIN
   DBMS_OUTPUT.PUT_LINE('v_Str = ' || v_Str);
   DBMS_OUTPUT.PUT_LINE('v_Num = ' || v_Num2);  
 --DBMS_OUTPUT.PUT_LINE('v_Num = ' || v_Num);
  END;

 --DBMS_OUTPUT.PUT_LINE('v_Str = ' || v_Str);   --error
END;
==============================================================
控制语句
1.条件语句
<1>
DECLARE
  v_flag BOOLEAN;
BEGIN
  IF v_flag THEN
   DBMS_OUTPUT.PUT_LINE('v_flag is TRUE');
  ELSIF NOT v_flag THEN
   DBMS_OUTPUT.PUT_LINE('v_flag is FALSE');
  ELSE
   DBMS_OUTPUT.PUT_LINE('v_flag is NULL');
  END IF;
END;

<2>
DECLARE
  v_flag BOOLEAN;
BEGIN
  IF v_flag THEN
   DBMS_OUTPUT.PUT_LINE('v_flag is TRUE');
  ELSIF v_flag IS NULL THEN
   DBMS_OUTPUT.PUT_LINE('v_flag is NULL');
  ELSE
   DBMS_OUTPUT.PUT_LINE('v_flag is FALSE');
  END IF;
END;

练习
lhj_test2.sql
如果工资大于1500,奖金按照20%计算.
如果工资在1000-1500,奖金按10%计算.
如果工资小于1000,奖金按照5%计算.
_______________________________________________
DECLARE
  v_sal s_emp.salary%TYPE;
  v_bonus s_emp.salary%TYPE;
BEGIN
  SELECT salary
   INTO v_sal
   FROM s_emp
  WHERE id=1;

  IF v_sal > 1500 THEN
   v_bonus := v_sal * 0.2;
  ELSIF v_sal>=1000 THEN
   v_bonus := v_sal * 0.1;
  ELSE
   v_bonus := v_sal * 0.05;
  END IF;

  DBMS_OUTPUT.PUT_LINE('BONUS: ' || v_bonus);
END;
_______________________________________________

2.循环语句
1>简单循环
LOOP
END LOOP;
例题1
lhj_test3.sql
求1-100的连加和
__________________________________
DECLARE
 v_ret NUMBER :=0;
 i     NUMBER :=1;
BEGIN
 LOOP
  v_ret := v_ret+i;
  i := i + 1;

  EXIT WHEN i>100;
 END LOOP;
 DBMS_OUTPUT.PUT_LINE(v_ret);
END;
____________________________________

2>WHILE循环
WHILE boolean_expression LOOP
END LOOP;
求1-100的连加和
_____________________________________
DECLARE
 v_ret NUMBER :=0;
 i     NUMBER :=1;
BEGIN
 WHILE i<=100 LOOP
  v_ret := v_ret+i;
  i := i + 1;
 
 END LOOP;
 DBMS_OUTPUT.PUT_LINE(v_ret);
END;
_____________________________________

3>FOR循环
FOR loop_counter IN[REVERSE] low_bound...high_bound LOOP
...
END LOOP;
求1-100的连加和
_____________________________________
DECLARE
 v_ret NUMBER :=0;
BEGIN
  for i IN 1..100 LOOP
  v_ret := v_ret+i;  
 
 END LOOP;
 DBMS_OUTPUT.PUT_LINE(v_ret);
END;
_____________________________________



练习
lhj_test4.sql
1>从s_emp表中循环找出id为1-5的员工,把结果保存在table类型的变量里。
2>循环的从table变量中把5名员工信息取出来依次输出
方法一:
_______________________________________________________________
DECLARE
 TYPE t_emp IS TABLE OF s_emp%ROWTYPE INDEX BY BINARY_INTEGER;
 v_emp t_emp;
 i     BINARY_INTEGER :=1;
 j     BINARY_INTEGER :=1;

BEGIN
 WHILE i<=5 LOOP
  SELECT *
   INTO v_emp(i)
   FROM s_emp
  WHERE id = i;

  i := i + 1;  
 END LOOP;

 LOOP
  DBMS_OUTPUT.PUT_LINE(v_emp(j).id||' '||v_emp(j).first_name);

   j := j+1;
   EXIT WHEN j>5;
 END LOOP;

END;
________________________________________________________________

方法二:
for 不用为变量v_cnt声明就可以用,编译器会根据 1..5自动为
s_emp声明,并且可以自动加1.
________________________________________________________
DECLARE
 v_emp s_emp%ROWTYPE;
BEGIN
  for v_cnt IN 1..5 LOOP   
  SELECT *
    INTO v_emp
    FROM s_emp
  WHERE id = v_cnt;

  DBMS_OUTPUT.PUT_LINE(v_emp.id||' '||v_emp.first_name);
 END LOOP;
 
END;

1 Carmen
2 LaDoris
3 Midori
4 Mark
5 Audry
______________________________________________________
DECLARE
 v_emp s_emp%ROWTYPE;
BEGIN
  for v_cnt IN REVERSE 1..5 LOOP   
  SELECT *
    INTO v_emp
    FROM s_emp
  WHERE id = v_cnt;

  DBMS_OUTPUT.PUT_LINE(v_emp.id||' '||v_emp.first_name);
 END LOOP;
 
END;
//REVERSE从上限值到下限值递减循环.
5 Audry
4 Mark
3 Midori
2 LaDoris
1 Carmen
_______________________________________________________

SQL in PL/SQL
动态SQL
lhj_test6.sql
__________________________________________________________________
DECLARE
   v_Str VARCHAR2(400);
BEGIN
   v_Str := 'create table temp_lhj(id number,coll varchar2(20))';
  EXECUTE IMMEDIATE v_Str;
END;
__________________________________________________________________

DECLARE
  v_Date VARCHAR2(20);
BEGIN
  v_Date := to_char(sysdate,'yyyy-mm-dd hh24:mi:ss');
  DBMS_OUTPUT.PUT_LINE(v_Date);
END;
______________________________________________________


======================================================================

Cursor游标
例:lhj_test7.sql
1>________________________________________________________________
DECLARE
  v_deptId   s_emp.dept_id%TYPE :=31;
  v_emp      s_emp%ROWTYPE;
 
  CURSOR  cur_emp1 IS
    SELECT * FROM s_emp
    WHERE dept_id = v_deptId;
BEGIN
 --v_deptId := 50;
   OPEN cur_emp1;
 
   FETCH cur_emp1 INTO v_emp;
   DBMS_OUTPUT.PUT_LINE(v_emp.id||' '||v_emp.first_name);

   FETCH cur_emp1 INTO v_emp;
   DBMS_OUTPUT.PUT_LINE(v_emp.id||' '||v_emp.first_name);

   CLOSE cur_emp1;
 
END;
2>简单循环
_______________________________________________________________
DECLARE
  v_deptId   s_emp.dept_id%TYPE :=31;
  v_emp      s_emp%ROWTYPE;
 
  CURSOR  cur_emp1 IS
    SELECT * FROM s_emp
    WHERE dept_id = v_deptId;
BEGIN
   OPEN cur_emp1;
   LOOP
   FETCH cur_emp1 INTO v_emp;
   EXIT WHEN cur_emp1%NOTFOUND;
   DBMS_OUTPUT.PUT_LINE(v_emp.id||' '||v_emp.first_name);   
   
   END LOOP;

   CLOSE cur_emp1;
 
END;

lhj_test8.sql
3>while循环
____________________________________________________
DECLARE
  v_deptId   s_emp.dept_id%TYPE :=31;
  v_emp      s_emp%ROWTYPE;
 
  CURSOR  cur_emp1 IS
    SELECT * FROM s_emp
    WHERE dept_id = v_deptId;
BEGIN
   OPEN cur_emp1;

   FETCH cur_emp1 INTO v_emp;

   while cur_emp1%FOUND  LOOP      
   DBMS_OUTPUT.PUT_LINE(v_emp.id||' '||v_emp.first_name);
   FETCH cur_emp1 INTO v_emp;  
   
   END LOOP;

   CLOSE cur_emp1;
 
END;
4>for循环
___________________________________________________________
DECLARE
  v_deptId   s_emp.dept_id%TYPE :=31;  
 
  CURSOR  cur_emp1 IS
    SELECT *
     FROM s_emp
    WHERE dept_id = v_deptId;
BEGIN
   FOR v_emp IN cur_emp1 LOOP       
     DBMS_OUTPUT.PUT_LINE(v_emp.id||' '||v_emp.first_name);   
   END LOOP;   
 
END;

FOR循环不需要做变量声明,不用OPEN,FETCH语句 for采用隐式游标.
FOR 会根据提供的查询语句,来确定v_emp的类型.*代表和s_emp表结构相同.
___________________________________________________________

带参数的游标
游标可以带多个参数cur_emp1(p_did s_emp.dept_id%TYPE,p_id NUMBER).
cur_emp1(p_did NUMBER)
p_did     如果只写成NUMBER(标量)时不要叫精度,和刻度NUMBER(4,2)
建议使用TYPE,ROWTYPE

DECLARE   
  v_emp s_emp%ROWTYPE;
  CURSOR  cur_emp1(p_did s_emp.dept_id%TYPE) IS
    SELECT *
     FROM s_emp
    WHERE dept_id = P_did;
BEGIN
   OPEN cur_emp1(31);
   LOOP
     FETCH cur_emp1 INTO v_emp;
     EXIT WHEN cur_emp1%NOTFOUND;
        
     DBMS_OUTPUT.PUT_LINE(v_emp.id||' '||v_emp.first_name);   
   END LOOP;   
   CLOSE cur_emp1;

 /* FOR v_emp IN cur_emp1(31) LOOP       
     DBMS_OUTPUT.PUT_LINE(v_emp.id||' '||v_emp.first_name);   
   END LOOP;  */
 
END;
________________________________________________________________

====================================================================
Handle Exception
oracle预定义异常
_________________________________________________
DECLARE
   v_emp s_emp%ROWTYPE;
BEGIN
   SELECT *
     INTO v_emp
     FROM s_emp
   WHERE id = 100;

  DBMS_OUTPUT.PUT_LINE('emp: '||v_emp.id);
EXCEPTION
   WHEN NO_DATA_FOUND THEN
     DBMS_OUTPUT.PUT_LINE('emp : no data in emp');
END;
___________________________________________________

自定义异常
___________________________________________________________
DECLARE
   e_MyException EXCEPTION;

   v_emp s_emp%ROWTYPE;
BEGIN
   SELECT *
     INTO v_emp
     FROM s_emp
   WHERE id = 100;  --id=1|id=17
 
  IF v_emp.salary < 1000 THEN
    RAISE e_MyException;
  END IF;

  DBMS_OUTPUT.PUT_LINE('emp: '||v_emp.id||' '||v_emp.salary);
EXCEPTION
   WHEN NO_DATA_FOUND THEN
     DBMS_OUTPUT.PUT_LINE('emp : no data in emp');

   WHEN e_MyException THEN
     DBMS_OUTPUT.PUT_LINE('emp : salary is too low');
     UPDATE s_emp SET salary = 1000
         WHERE id = v_emp.id;

   WHEN OTHERS THEN
     DBMS_OUTPUT.PUT_LINE('emp : other exception');
END;
//匿名块
__________________________________________________

Sub program
带名块
procedure,function,package,trigger
lhj_pro1.sql
不带参数的存储过程
_______________________________________
CREATE OR REPLACE PROCEDURE  pro_lhj1 AS
BEGIN
   DBMS_OUTPUT.PUT_LINE('Hello,world');
END;
________________________________________

lhj_pro11.sql
______________________________________
DECLARE
   v_name   s_emp.first_name%TYPE;
BEGIN
  --pro_lhj1;
  -- pro_lhj1(1);--in 模式的参数,从调用者的地方传值给存储过程
  pro_hello(1,v_name);

  DBMS_OUTPUT.PUT_LINE('hello, '||v_name);
END;
_____________________________________

===============================================================
带参数的存储过程(in模式)lhj_pro1.sql
______________________________________________________
CREATE OR REPLACE PROCEDURE  pro_lhj1(
      p_id s_emp.id%TYPE) AS
      v_emp s_emp%ROWTYPE;
BEGIN
   SELECT * INTO v_emp
     FROM s_emp
   WHERE id = p_id;

   DBMS_OUTPUT.PUT_LINE('hello, '||v_emp.first_name);
END;
_____________________________________________________

lhj_pro11.sql
______________________________________

BEGIN   
   pro_lhj1(1);--in 模式的参数,从调用者的地方传值给存储过程  
END;
_____________________________________
=================================================================
带参数的存储过程(out模式)lhj_pro1.sql
__________________________________________________________
CREATE OR REPLACE PROCEDURE  pro_lhj1(
      p_id s_emp.id%TYPE,
      p_name OUT s_emp.first_name%TYPE) AS
    v_emp s_emp%ROWTYPE;
BEGIN
   SELECT * INTO v_emp
     FROM s_emp
   WHERE id = p_id;
   
   p_name := v_emp.first_name;
   --DBMS_OUTPUT.PUT_LINE('hello, '||v_emp.first_name);
END;
___________________________________________________________

lhj_pro11.sql
______________________________________
DECLARE
   v_name   s_emp.first_name%TYPE;
BEGIN   
  pro_lhj1(1,v_name);
--pro_lhj1(p_name=>v_name,p_id=>1);   名字标示法
--pro_lhj1(1,p_name=>v_name);   两种方法混用时,
                                  第一个必须用位置标示法

  DBMS_OUTPUT.PUT_LINE('hello, '||v_name);
END;
_____________________________________

例:加法
lhj_pro2.sql
_____________________________________
CREATE OR REPLACE PROCEDURE pro_lhj2(
   p_a NUMBER,
   p_b NUMBER,
   p_ret OUT NUMBER) AS
   v_ret NUMBER;
BEGIN
   v_ret := p_a+p_b;
   p_ret := v_ret;
END;
______________________________________

lhj_pro22.sql
______________________________________
DECLARE
   v_name   s_emp.first_name%TYPE;
   v_ret    NUMBER;
BEGIN   
  pro_lhj1(1,v_name);
  DBMS_OUTPUT.PUT_LINE('hello, '||v_name);

  pro_lhj2(2,3,v_ret);
 
  DBMS_OUTPUT.PUT_LINE('2+3= '||v_ret);
END;
_____________________________________

================================================================
FUNCTION

lhj_fun1.sql
__________________________________________    
CREATE OR REPLACE FUNCTION fun_lhj1(
    p_a NUMBER,
    p_b NUMBER) RETURN NUMBER
IS
   v_ret NUMBER;
BEGIN
   v_ret :=p_a+p_b;
   RETURN v_ret;
END;
__________________________________________
lhj_fun11.sql
________________________________________
DECLARE
  v_ret NUMBER;
BEGIN
  v_ret := fun_add(2,3);
  DBMS_OUTPUT.PUT_LINE('2+3='||v_ret);
END;
________________________________________

=================================================================
Package
lhj_pack1.sql
________________________________________
CREATE OR REPLACE PACKAGE pack_lhj1 AS
   v_emp s_emp%ROWTYPE;

   PROCEDURE addEmp(p_emp s_emp%ROWTYPE);
END pack_lhj1;
________________________________________

lhj_pack2.sql
___________________________________________________
CREATE OR REPLACE PACKAGE BODY pack_lhj1 AS
    PROCEDURE addEmp(p_emp s_emp%ROWTYPE) AS
    BEGIN
     INSERT INTO s_emp(id,last_name,first_name,salary)
     VALUES(s_emp_lhjid.nextval,p_emp.last_name, --s_emp_lhjid序列名
            p_emp.first_name,p_emp.salary);
    
     COMMIT;
   END addEmp;
END pack_lhj1;
________________________________________________________

lhj_pack12.sql
______________________________________
BEGIN
   pack_lhj1.v_emp.last_name := 'wang';
   pack_lhj1.v_emp.first_name := 'wu';
   pack_lhj1.v_emp.salary := 2000;

   pack_lhj1.addEmp(pack_lhj1.v_emp);
END;
______________________________________

作业:
1:(存储过程)s_emp
已知员工id,找出员工的领导姓名
2:(函数)
写一个函数,给出地区id(s_region),
          找出此地区下工资最高的员工(s_emp)所在的部门名称(s_dept).
         
1.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
lhj_test_pro1.sql
____________________________________________
CREATE OR REPLACE PROCEDURE pro_lhj_test1(
       v_id s_emp.id%TYPE,
       v_fname OUT s_emp.first_name%TYPE) AS
       
   p_fname s_emp.first_name%TYPE;
BEGIN
   SELECT b.first_name INTO p_fname
     FROM s_emp a,s_emp b
   where a.id = v_id and  a.manager_id=b.id;
   v_fname := p_fname;
END;
___________________________________________

lhj_test_pro11.sql
_____________________________________________________________
DECLARE
   t_name s_emp.first_name%TYPE;
BEGIN
   pro_lhj_test1(2,v_fname=>t_name);
   DBMS_OUTPUT.PUT_LINE(t_name||' is id=2 employees manager');
END;
_____________________________________________________________
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
lhj_test_pro2.sql
______________________________________________________
CREATE OR REPLACE FUNCTION fun_lhj_test1(
      r_id s_region.id%TYPE) RETURN s_dept.name%TYPE
IS
   f_name s_dept.name%TYPE;
BEGIN
   select name
   into f_name
   from s_dept where id=(
   select dept_id from s_emp where salary=(
   select max(salary) from s_emp where dept_id in(
   select id from s_dept where region_id = r_id)));

   RETURN f_name;
END;
_______________________________________________________
lhj_test_pro22.sql
___________________________________________________
DECLARE
   v_name s_dept.name%TYPE;
BEGIN
   v_name := fun_lhj_test1(1);

   DBMS_OUTPUT.PUT_LINE(v_name);   
END;
_____________________________________________________  
      





* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值