源码-PL/SQL从入门到精通-第十七章-面向对象编程-Part 1

原来PL/SQL也支持面向对象编程,有了Java基础,这章不难理解。

有个问题:对象定义真不支持布尔类型? 我的Java程序中布尔型可是很常用的啊。不过肯定有其他的替代解决方案吧疑问

--第17章开始
--代码17.1 定义employee_obj对象类型规范
--定义对象类型规范employee_obj
CREATE OR REPLACE TYPE employee_obj AS OBJECT (
--定义对象类型属性
empno         NUMBER(4),
ename         VARCHAR2(20),
job           VARCHAR2(20),
sal           NUMBER(10,2),
comm          NUMBER(10,2),
deptno        NUMBER(4),
--定义对象类型方法
MEMBER PROCEDURE Change_sal(p_empno NUMBER,p_sal NUMBER),
MEMBER PROCEDURE Change_comm(p_empno NUMBER,p_comm NUMBER),
MEMBER PROCEDURE Change_deptno(p_empno NUMBER,p_deptno NUMBER),
MEMBER FUNCTION get_sal(p_empno NUMBER) RETURN NUMBER,
MEMBER FUNCTION get_comm(p_empno NUMBER) RETURN NUMBER,
MEMBER FUNCTION get_deptno(p_empno NUMBER) RETURN INTEGER
) NOT FINAL;      --指定该类可以被继承,如果指定FINAL,表示该类无法被继承



--代码 17.2 定义对象类型体
CREATE OR REPLACE TYPE BODY employee_obj
AS
   MEMBER PROCEDURE change_sal (p_empno NUMBER, p_sal NUMBER)
   IS                          --定义对象成员方法,更改员工薪资
   BEGIN
      UPDATE emp
         SET sal = p_sal
       WHERE empno = p_empno;
   END;
   MEMBER PROCEDURE change_comm (p_empno NUMBER, p_comm NUMBER)
   IS                         --定义对象成员方法,更改员工提成
   BEGIN
      UPDATE emp
         SET comm = p_comm
       WHERE empno = p_empno;
   END;
   MEMBER PROCEDURE change_deptno (p_empno NUMBER, p_deptno NUMBER)
   IS                        --定义对象成员方法,更改员工部门
   BEGIN
      UPDATE emp
         SET deptno = p_deptno
       WHERE empno = p_empno;
   END;
   MEMBER FUNCTION get_sal (p_empno NUMBER)
      RETURN NUMBER
   IS                        --定义对象成员方法,获取员工薪资
      v_sal   NUMBER (10, 2);
   BEGIN
      SELECT sal
        INTO v_sal
        FROM emp
       WHERE empno = p_empno;
      RETURN v_sal;
   END;
   MEMBER FUNCTION get_comm (p_empno NUMBER)
      RETURN NUMBER
   IS                        --定义对象成员方法,获取员工提成
      v_comm   NUMBER (10, 2);
   BEGIN
      SELECT comm
        INTO v_comm
        FROM emp
       WHERE empno = p_empno;
      RETURN v_comm;
   END;
   MEMBER FUNCTION get_deptno (p_empno NUMBER)
      RETURN INTEGER
   IS                        --定义对象成员方法,获取员工部门
      v_deptno   INT;
   BEGIN
      SELECT deptno
        INTO v_deptno
        FROM emp
       WHERE empno = p_empno;
      RETURN v_deptno;
   END;
END;

--代码17.3 定义对象的属性
--定义对象类型规范employee_obj
CREATE OR REPLACE TYPE employee_property AS OBJECT (
--定义对象类型属性
empno         NUMBER(4),
ename         VARCHAR2(20),
job           VARCHAR2(20),
sal           NUMBER(10,2),
comm          NUMBER(10,2),
deptno        NUMBER(4)
) NOT FINAL;   --对象类型可以被继承


--代码17.4 实例化对象并设置或获取对象属性
DECLARE
   v_emp   employee_property;        --定义对象类型
   v_sal   v_emp.sal%TYPE;           --定义对象类型中与sal类型相同的薪资变量
BEGIN
   --初始化对象类型,v_emp是一个对象的实例
   v_emp := employee_property (7890, '赵五', '销售人员', 5000, 200, 20);
   v_sal := v_emp.sal;               --为变量赋对象实例的值
   --获取对象类型的属性进行显示
   DBMS_OUTPUT.put_line (v_emp.ename || ' 的薪资是:' || v_sal);
END;

--代码17.5 使用Member和Static成员方法(不好调试啊!->调试通过!)
--定义对象类型规范employee_salobj

CREATE OR REPLACE TYPE employee_method AS OBJECT (
--定义对象类型属性
   empno    NUMBER (4),
   sal      NUMBER (10, 2),
   comm     NUMBER (10, 2),
   deptno   NUMBER (4),
--定义对象类型方法
   MEMBER PROCEDURE change_sal,          --实例方法,可以访问对象本身的属性
   MEMBER FUNCTION get_sal RETURN NUMBER,   
   --静态方法,不能访问对象本身的属性,只能访问静态数据
   STATIC PROCEDURE change_deptno (p_empno NUMBER, p_deptno NUMBER), 
   STATIC FUNCTION get_sal (p_empno NUMBER) RETURN NUMBER
)
NOT FINAL;             --指定该类可以被继承,如果指定FINAL,表示该类无法被继承
----------------------------------------------------------------------------------
--定义employee_method对象类型体
CREATE OR REPLACE TYPE BODY employee_method
AS
   MEMBER PROCEDURE change_sal
   IS
   BEGIN
      SELF.sal := SELF.sal * 1.12;        --使用SELF关键字
   END;
   MEMBER FUNCTION get_sal
      RETURN NUMBER
   IS
   BEGIN
      RETURN sal;                        --返回员工薪资
   END;
   STATIC PROCEDURE change_deptno (p_empno NUMBER, p_deptno NUMBER)
   IS                                    --定义对象成员方法,更改员工部门
   BEGIN
      UPDATE emp
         SET deptno = p_deptno
       WHERE empno = p_empno;
   END;
   STATIC FUNCTION get_sal (p_empno NUMBER)
      RETURN NUMBER
   IS                                     --定义对象成员方法,获取员工薪资
      v_sal   NUMBER (10, 2);
   BEGIN
      SELECT sal
        INTO v_sal
        FROM emp
       WHERE empno = p_empno;
      RETURN v_sal;
   END; 
END;


--代码17.6 Member和Static方法使用示例
DECLARE
   v_emp  employee_method;                    --定义employee_method对象类型的变量
BEGIN
   v_emp:=employee_method(5093,5000,200,20);   --实例化employee_method对象,现在v_emp是对象实例
   v_emp.change_sal;                           --设用对象实例方法,即MEMBER方法
   DBMS_OUTPUT.put_line('员工编号为:'||v_emp.empno||' 的薪资为:'||v_emp.get_sal);   
   --下面的代码调用STATIC方法更新emp表中员工编号为7369的部门编号为20.
   employee_method.change_deptno(5093,20);
   --下面的代码获取emp表中员工编号为7369的员工薪资。
  DBMS_OUTPUT.put_line('员工编号为5093的薪资为:'||employee_method.get_sal(5093)); 
END;   

drop trigger t_comm_sal;
select * from emp;

--代码17.7 访问对象类型的属性
--定义对象类型规范employee_salobj
CREATE OR REPLACE TYPE employee_salobj AS OBJECT (
--定义对象类型属性
   empno    NUMBER (4),
   sal      NUMBER (11, 2),
   comm     NUMBER (10, 2),
   deptno   NUMBER (4),
--定义对象类型方法
   MEMBER PROCEDURE change_sal,
   MEMBER PROCEDURE change_comm,
   MEMBER PROCEDURE change_deptno,
   MEMBER FUNCTION get_sal
      RETURN NUMBER,
   MEMBER FUNCTION get_comm
      RETURN NUMBER,
   MEMBER FUNCTION get_deptno
      RETURN INTEGER
)
NOT FINAL;             --指定该类可以被继承,如果指定FINAL,表示该类无法被继承
----------------------------------------------------------------------------------
--定义employee_salobj对象类型体
CREATE OR REPLACE TYPE BODY employee_salobj
AS
   MEMBER PROCEDURE change_sal
   IS
   BEGIN
      SELF.sal := SELF.sal * 1.12;        --使用SELF关键字
   END;
   MEMBER PROCEDURE change_comm
   IS
   BEGIN
      comm := comm * 1.12;               --不使用SELF关键字
   END;
   MEMBER PROCEDURE change_deptno
   IS
   BEGIN
      SELF.deptno := 20;                 --使用SELF关键字更改部门名称
   END;
   MEMBER FUNCTION get_sal
      RETURN NUMBER
   IS
   BEGIN
      RETURN sal;                        --返回员工薪资
   END;
   MEMBER FUNCTION get_comm
      RETURN NUMBER
   IS
   BEGIN
      RETURN SELF.comm;                  --返回员工提成
   END;
   MEMBER FUNCTION get_deptno
      RETURN INTEGER
   IS
   BEGIN
      RETURN SELF.deptno;               --返回员工部门编号
   END;
END;

--代码17.8 自定义构造函数
--定义对象类型规范
CREATE OR REPLACE TYPE salary_obj AS OBJECT (
percent        NUMBER(10,4),       --定义对象属性
sal          NUMBER(10,2),
--自定义构造函数
CONSTRUCTOR FUNCTION salary_obj(p_sal NUMBER) RETURN SELF AS RESULT)
INSTANTIABLE         --可实例化对象
FINAL;               --不可以继承
/
--定义对象类型体
CREATE OR REPLACE TYPE BODY salary_obj
AS
   --实现重载的构造函数
   CONSTRUCTOR FUNCTION salary_obj (p_sal NUMBER)
      RETURN SELF AS RESULT
   AS
   BEGIN
      SELF.sal := p_sal;          --设置属性值
      SELF.PERCENT := 1.12;       --为属性指定初值
      RETURN;
   END;
END;
/

DECLARE
   v_salobj1   salary_obj;
   v_salobj2   salary_obj;                 --定义对象类型
BEGIN
   v_salobj1 := salary_obj (1.12, 3000);   --使用默认构造函数
   v_salobj2 := salary_obj (2000);         --使用自定义构造函数
END;


--代码17.9 定义Map函数示例
--定义一个对象规范,该规范中包含MAP方法
CREATE OR REPLACE TYPE employee_map AS OBJECT (
--定义对象类型属性
   empno    NUMBER (4),
   sal      NUMBER (10, 2),
   comm     NUMBER (10, 2),
   deptno   NUMBER (4),
   MAP MEMBER FUNCTION convert RETURN REAL    --定义一个MAP方法
)
NOT FINAL;            
--定义一个对象类型体,实现MAP函数
CREATE OR REPLACE TYPE BODY employee_map AS
  MAP MEMBER FUNCTION convert RETURN REAL  IS   --定义一个MAP方法
  BEGIN
     RETURN sal+comm;                           --返回标量类型的值
  END;
END;         


--创建employee_map类型的对象表
CREATE TABLE emp_map_tab OF employee_map;
--向对象表中插入员工薪资信息对象。
INSERT INTO emp_map_tab VALUES(7123,3000,200,20);
INSERT INTO emp_map_tab VALUES(7124,2000,800,20);
INSERT INTO emp_map_tab VALUES(7125,5000,800,20);
INSERT INTO emp_map_tab VALUES(7129,3000,400,20);

SELECT VALUE(r) val,r.sal+r.comm FROM emp_map_tab r ORDER BY 1;


--代码17.10 定义Order函数示例
--定义一个对象规范,该规范中包含ORDER方法
CREATE OR REPLACE TYPE employee_order AS OBJECT (
--定义对象类型属性
   empno    NUMBER (4),
   sal      NUMBER (10, 2),
   comm     NUMBER (10, 2),
   deptno   NUMBER (4),
   ORDER MEMBER FUNCTION match(r employee_order) RETURN INTEGER    --定义一个ORDER方法
)
NOT FINAL; 
--定义一个对象类型体,实现ORDER函数
CREATE OR REPLACE TYPE BODY employee_order AS
  ORDER MEMBER FUNCTION match(r employee_order) RETURN INTEGER  IS   
  BEGIN
     IF ((SELF.sal+SELF.comm)<(r.sal+r.comm)) THEN
        RETURN -1;      --可为任何负数
     ELSIF ((SELF.sal+SELF.comm)>(r.sal+r.comm)) THEN
        RETURN 1;       --可为任何正数
     ELSE 
        RETURN 0;      --如果相等则为0
     END IF;
  END match;
END;   


DECLARE
   emp1 employee_order:=employee_order(7112,3000,200,20);    --定义员工1
   emp2 employee_order:=employee_order(7113,3800,100,20);    --定义员工2
BEGIN
   --对员工1和2进行比较,获取返回结果
   IF emp1>emp2 THEN
      DBMS_OUTPUT.put_line('员工1的薪资加提成比员工2大!');
   ELSIF emp1<emp2 THEN
      DBMS_OUTPUT.put_line('员工1的薪资加提成比员工2小!');
   ELSE
      DBMS_OUTPUT.put_line('员工1的薪资加提成与员工2相等!');
   END IF;
END;




--创建employee_order类型的对象表
CREATE TABLE emp_order_tab OF employee_order;
--向对象表中插入员工薪资信息对象。
INSERT INTO emp_order_tab VALUES(7123,3000,200,20);
INSERT INTO emp_order_tab VALUES(7124,2000,800,20);
INSERT INTO emp_order_tab VALUES(7125,5000,800,20);
INSERT INTO emp_order_tab VALUES(7129,3000,400,20);
SELECT VALUE(r) val,r.sal+r.comm FROM emp_order_tab r ORDER BY 1;

--方法中定义的


--代码17.11 使用对象类型
DECLARE
   o_emp   employee_order;                             --定义对象实例,初始状态下为NULL
BEGIN
   o_emp := employee_order (7123, 3000, 200, 20);      --使用构造函数声明对象
   DBMS_OUTPUT.put_line (   '员工编号为:'
                         || o_emp.empno
                         || '的薪资和提成为:'
                         || (o_emp.sal + o_emp.comm)
                        );
END;


--代码17.12 在子程序中使用对象类型
--使用对象类型作为过程的形式参数
CREATE OR REPLACE PROCEDURE changesalary(p_emp IN employee_order) 
AS
BEGIN
   IF p_emp IS NOT NULL THEN         --如果对象类型已经被实例化
     --更新emp表
     UPDATE emp SET sal=p_emp.sal,comm=p_emp.comm WHERE empno=p_emp.empno;
   END IF;
END changesalary;
--使用对象类型作为函数的传入传出参数
CREATE OR REPLACE FUNCTION getsalary(p_emp IN OUT employee_order) RETURN NUMBER
AS
BEGIN
   IF p_emp IS NOT NULL THEN                      --如果对象类型没有被实例化
      p_emp:=employee_order(7125,5000,800,20);    --实例化对象类型
   END IF;
   RETURN p_emp.sal+p_emp.comm;                   --返回对象类型的薪资和提成汇总
END;


DECLARE
   o_emp  employee_order;
BEGIN
   o_emp.empno:=7301;   --错误:该对象实例还没有被初始化就进行了赋值
END;


--好的编程习惯:定义变量时进行初始化
DECLARE
   o_emp   employee_order := 
              employee_order (NULL, NULL, NULL, NULL); --初始化对象类型
BEGIN
   o_emp.empno := 7301;                                --为对象类型赋值
   o_emp.sal := 5000;
   o_emp.comm := 300;
   o_emp.deptno := 20;
END;

--代码17.13 调用静态方法与示例方法示例
--employee_method对象类型的实例方法与静态方法列表
CREATE OR REPLACE TYPE employee_method AS OBJECT (
   empno    NUMBER (4),
   sal      NUMBER (11, 2),
   comm     NUMBER (10, 2),
   deptno   NUMBER (4),
--定义对象类型方法
   MEMBER PROCEDURE change_sal,            --实例方法,可以访问对象本身的属性
   MEMBER FUNCTION get_sal RETURN NUMBER,   
   --静态方法,不能访问对象本身的属性,只能访问静态数据
   STATIC PROCEDURE change_deptno (empno NUMBER, deptno NUMBER), 
   STATIC FUNCTION get_sal (empno NUMBER) RETURN NUMBER
)
NOT FINAL;    
--演示调用employee_method的实例方法与静态方法 (调试未成功)
DECLARE
   o_emp employee_method:=employee_method(5093,5000,800,20);
   v_sal NUMBER(11,2); 
BEGIN
   v_sal:=o_emp.get_sal;                       --调用对象实例方法
   DBMS_OUTPUT.put_line('对象实例级别的工资为:'||v_sal);
   v_sal:=employee_method.get_sal(o_emp.empno); --调用静态方法
   DBMS_OUTPUT.put_line('对象类型级别的工资为:'||v_sal);   
END;


DROP TYPE APPS.ADDRESS_TYPE;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值