---对象基本声明、实现、使用
--对象类型,类似与JAVA中的类,通俗的讲,就是捆绑了相关函数和过程的记录类型。

  1. ---对象声明
  2. --create type 创建一个对象类型的规范部分
  3. create or replace type hello_object as object (
  4. obj_name varchar2(100),
  5. constructor function hello_object return self as result,
  6. constructor function hello_object(obj_name varchar2 /*:='world'*/) return self as result,
  7. member function to_string return varchar2
  8. ) instantiable not final;
  9.  
  10. -- obj_name :实例变量
  11. -- constructor function:声明 构造函数,构造函数可以重载,但名字必须更类名称一致
  12. -- self as result : 构造函数总是返回一个对象实例,java中的this
  13.  
  14. -- member procedure/function:定义成员函数,成员函数只能用于对象实例
  15. -- not final 表示可以被继承
  16. -- instantiable:表示可实例化,如果指定NOT INSTANTIABLE ,则这种类型只能做一个基类
  17. --每个成员之间,使用逗号分隔
  18. --构造函数要尽可能多的给当前对象任何一个属性赋值

--定义对象类型后,就可以创建对象体,跟创建包体规则一样

  1. --create type body 创建对象体
  2. create or replace type body hello_object as
  3. --默认构造方法
  4. constructor function hello_object return self as result is
  5. v_obj hello_object := hello_object('generic object');
  6. begin
  7. self := v_obj;
  8. return;
  9. end hello_object;
  10. --重写构造方法
  11. constructor function hello_object(obj_name varchar2) return self as result is
  12. begin
  13. self.obj_name := obj_name;
  14. return; -- 返回一个副本,即对象实例的当前内存引用
  15. end hello_object;
  16. --成员函数
  17. member function to_string return varchar2 is
  18. begin
  19. return 'hello,' || self.obj_name ;
  20. end to_string;
  21.  
  22. end;
  23. /

--不懂Java?self只不过是在编写成员方法时,用来引用调用当前对象的一个手段,可以用SELF指代对象自己,也可以
--用句点法来引用对象的属性或者方法

--缺省情况下,SELF是函数的IN 变量,是过程和构造函数的IN OUT变量 。怎么理解?
--可以把SELF作为第一个形参来改变缺省模式

--如果另外一个带参数的构造函数,使用了默认的入参,则这种构造函数,跟默认构造函数会有冲突
--当调用无入参的构造函数构建对象时,会出现多个可调用的构造函数,引发混乱报错

--使用对象类型

  1. select hello_object().to_string() from dual;
  2. select hello_object('world').to_string() from dual;
  3.  
  4. declare
  5. v_obj hello_object := hello_object();
  6. begin
  7.  
  8. dbms_output.put_line(v_obj.obj_name);
  9. dbms_output.put_line(v_obj.to_string());
  10. end;
  11. /
  12.  
  13. --对象在运行时创建并丢弃,这种对象就叫做瞬态对象;有瞬态的就有持久型对象
  14. create table sample_object(persistent hello_object); --创建表,字段是对象类型
  15. insert into sample_object values( hello_object());
  16. insert into sample_object values( hello_object('world'));
  17. select * from sample_object ;
  18.  
  19. select t.persistent.obj_name from sample_object t ;
  20. --两种调用方式
  21. select t.persistent.to_string() from sample_object t ;
  22. select treat(t.persistent as hello_object).to_string() from sample_object t ;
  23.  
  24. drop table sample_object;
  1. --实现gettersetter
  2. --getter是一个方法,可以达到对象内部获取一些信息,setter也是一个方法,可以发送信息到对象内部
  3. --设置实例变量
  4. create or replace type hello_object as object (
  5. obj_name varchar2(100),
  6. constructor function hello_object return self as result,
  7. constructor function hello_object(obj_name varchar2/* :='world'*/) return self as result,
  8. member function to_string return varchar2,
  9. member function get_name return varchar2,
  10. member procedure set_name(i_name in varchar2)
  11. ) instantiable not final;
  12.  
  13. create or replace type body hello_object as
  14. --默认构造方法
  15. constructor function hello_object return self as result is
  16. v_obj hello_object := hello_object('generic object');
  17. begin
  18. self := v_obj;
  19. return;
  20. end hello_object;
  21. --重写构造方法
  22. constructor function hello_object(obj_name varchar2) return self as result is
  23. begin
  24. self.obj_name := obj_name;
  25. return; -- 返回一个副本,即对象实例的当前内存引用
  26. end hello_object;
  27. --成员函数
  28. member function to_string return varchar2 is
  29. begin
  30. return 'hello,' || self.obj_name ;
  31. end to_string;
  32. member function get_name return varchar2 is
  33. begin
  34. return self.obj_name;
  35. end get_name;
  36.  
  37. member procedure set_name(i_name in varchar2)is
  38. begin
  39. self.obj_name := i_name;
  40. end set_name;
  41. end;
  42. /
  43. declare
  44. v_obj hello_object := hello_object();
  45. begin
  46. dbms_output.put_line(v_obj.get_name());
  47. v_obj.set_name('test');
  48. dbms_output.put_line(v_obj.get_name());
  49. v_obj.obj_name :='ssdddee';
  50. dbms_output.put_line(v_obj.obj_name);
  51. end;
  52. /

--实现静态方法

  1. create or replace type hello_object as object (
  2. obj_name varchar2(100),
  3. constructor function hello_object return self as result,
  4. constructor function hello_object(obj_name varchar2/* :='world'*/) return self as result,
  5. member function to_string return varchar2,
  6. member function get_name return varchar2,
  7. member procedure set_name(i_name in varchar2),
  8. static procedure print
  9. ) instantiable not final;
  10.  
  11. create or replace type body hello_object as
  12. --默认构造方法
  13. constructor function hello_object return self as result is
  14. v_obj hello_object := hello_object('generic object');
  15. begin
  16. self := v_obj;
  17. return;
  18. end hello_object;
  19. --重写构造方法
  20. constructor function hello_object(obj_name varchar2) return self as result is
  21. begin
  22. self.obj_name := obj_name;
  23. return; -- 返回一个副本,即对象实例的当前内存引用
  24. end hello_object;
  25. --成员函数
  26. member function to_string return varchar2 is
  27. begin
  28. return 'hello,' || self.obj_name ;
  29. end to_string;
  30. member function get_name return varchar2 is
  31. begin
  32. return self.obj_name;
  33. end get_name;
  34.  
  35. member procedure set_name(i_name in varchar2)is
  36. begin
  37. self.obj_name := i_name;
  38. end set_name;
  39. static procedure print is
  40. begin
  41. dbms_output.put_line('welcome to learn object');
  42. end print ;
  43.  
  44. end;
  45. /

--使用static来声明一个静态方法或函数
--静态方法允许像使用标准包一样使用对象类型。可以使用静态函数和过程来打印常量和消息
--但不能使用其访问实例变量。静态函数可以返回一个实例化类
--静态方法中不能使用SELF,因为对于静态方法而言没有当前对象

begin
hello_object.print();
end;
/
--比较对象
--先来看一个例子

  1. declare
  2.  
  3. v_obj1 hello_object := hello_object();
  4. v_obj2 hello_object := hello_object();
  5. begin
  6.  
  7. if v_obj1 = v_obj2 then
  8. dbms_output.put_line('equal');
  9. else
  10. dbms_output.put_line('not equal');
  11. end if;
  12. end;
  13. /
  14. --怎样比较两个对象呢?比如数值变量,我们可以直接比较数值来判断大小,对象却没有那么方便
  15. --但我们可以给对象指定比较的规则,规定在什么情况下相等,什么情况下哪个比较大,哪个比较小
  16. --使用MAP或者ORDER方法,可以来定义比较规则

--Map函数比较

  1. --Map 函数不接受形参,只返回CHARDATE ,NUMBERVARCHAR2的标量类型
  2. create or replace type map_comp is object (
  3. cmp_data varchar2(20),
  4. constructor function map_comp(cmp_data varchar2) return self as result,
  5. map member function equal return varchar2
  6. );
  7. create or replace type body map_comp is
  8.  
  9. constructor function map_comp(cmp_data varchar2) return self as result
  10. is
  11. begin
  12. self.cmp_data := cmp_data;
  13. return ;
  14. end map_comp;
  15. map member function equal return varchar2 is
  16. begin
  17. return self.cmp_data;
  18. end equal;
  19.  
  20. end ;
  21. /
  22. declare
  23. v_data1 map_comp := map_comp('a');
  24. v_data2 map_comp := map_comp('a');
  25. v_data3 map_comp := map_comp('b');
  26.  
  27. begin
  28. if v_data1 = v_data2 then
  29. dbms_output.put_line('equal');
  30. else
  31. dbms_output.put_line('not equal');
  32. end if;
  33.  
  34. if v_data1 = v_data3 then
  35. dbms_output.put_line('equal');
  36. else
  37. dbms_output.put_line('not equal');
  38. end if;
  39.  
  40. end;
  41. /

--作业:给定上述对象的对象列表,使用冒泡排序法进行排序

  1. --ORDER 方法比较
  2. --order 函数运行将任何数据类型定义为形参。通过将形参定义为相同的对象类型,可以模拟JAVA中的
  3. --对象比较方法,这样可以把某个对象的副本传递给另一个对象,然后比较这两个对象
  4.  
  5. create or replace type order_comp is object (
  6. first_name varchar2(100),
  7. second_name varchar2(100),
  8. constructor function order_comp(first_name varchar2,second_name varchar2) return self as result,
  9. order member function equal(i_obj order_comp) return number,
  10. member function to_string return varchar2
  11. ) instantiable not final; --没有指定NOT FINAL 默认是FINAL
  12.  
  13. create or replace type body order_comp is
  14.  
  15. constructor function order_comp(first_name varchar2,
  16. second_name varchar2) return self as result is
  17. begin
  18. self.first_name := first_name;
  19. self.second_name := second_name;
  20. return;
  21. end order_comp;
  22. order member function equal(i_obj order_comp) return number is
  23. begin
  24.  
  25. if self.first_name > i_obj.first_name then
  26. return -1;
  27. elsif self.first_name = i_obj.first_name
  28. and self.second_name > i_obj.second_name then
  29. return -1;
  30. elsif self.first_name = i_obj.first_name
  31. and self.second_name = i_obj.second_name then
  32. return 0 ;
  33. else
  34. return 1 ;
  35. end if;
  36. end equal;
  37.  
  38. member function to_string return varchar2 is
  39. begin
  40. return self.first_name||'-'||self.second_name;
  41. end to_string;
  42.  
  43. end;
  44. /
  45. --如果self < i_obj order函数返回任意负数 -1
  46. --如果SELF = i_obj 返回 0
  47. --如果SELF > i_obj 返回 任意正数 1
  48. declare
  49. v_data1 order_comp := order_comp('a','c');
  50. v_data2 order_comp := order_comp('a','d');
  51. v_data3 order_comp := order_comp('b','s');
  52.  
  53. begin
  54. if v_data1< v_data2 then
  55. dbms_output.put_line('yes');
  56. else
  57. dbms_output.put_line('no');
  58. end if;
  59. end;
  60. /
  61.  
  62. ---map order在同一个对象类型中不能并存,只能使用一个
  63. --当有大量的对象需要排序和比较时,比如在SQL语句中,ORACLE建议使用MAP
  64. --ORACLE并不关系方法的名字,我们可以任意起名
  65. --子类型也可以有MAP方法,不过只有当基类也有这个方法时才行
  66. --子类型不能有ORDER方法;我们必须聪明地把所有比较都放在基类中

---继承和多态
--跟JAVA中类可以被继承外,对象类型也可以被继承
--在其它语言中,比如JAVA都有一个基类型,比如Object,在ORACLE里没有定义一个主的基类

  1. drop type order_subcomp;
  2. ---under 标识子类型的关键字
  3. create or replace type order_subcomp under order_comp
  4. (
  5. salucation varchar2(20),
  6. constructor function order_subcomp(first_name varchar2,
  7. second_name varchar2,
  8. salucation varchar2)
  9. return self as result,
  10. overriding member function to_string return varchar2
  11. )instantiable final;
  12.  
  13. create or replace type body order_subcomp is
  14. constructor function order_subcomp(first_name varchar2,
  15. second_name varchar2,
  16. salucation varchar2)
  17. return self as result is
  18. begin
  19. self.first_name := first_name;
  20. self.second_name := second_name;
  21. self.salucation := salucation;
  22. return;
  23. end order_subcomp;
  24. overriding member function to_string return varchar2 is
  25.  
  26. begin
  27. return(self as order_comp) .to_string() || ',' || self.salucation;
  28. end to_string;
  29.  
  30. end;
  31. /

---使用(self as supertype) 来调用父类的方法,11g及之后可以这样使用
--11g之前,这是不可能的

  1. declare
  2. v_data1 order_subcomp := order_subcomp('a','c','s');
  3. v_data2 order_subcomp := order_subcomp('a','d','t');
  4. v_data3 order_subcomp := order_subcomp('b','s','y');
  5.  
  6. v_parent order_comp ;
  7.  
  8. begin
  9. if v_data1< v_data2 then
  10. dbms_output.put_line('small');
  11. else
  12. dbms_output.put_line('not small');
  13. end if;
  14.  
  15. v_parent := v_data1;
  16. dbms_output.put_line(v_data1.to_string());
  17. dbms_output.put_line(v_parent.to_string());
  18. end;
  19. /
  20. --声明子类型时,父类型中的属性不用列出,因其自动继承
  21. --子类型构建,将变量分配给父类型属性
  22. --子类型可以访问父类型的构造函数
  23. --子类型不能覆写父类型的构造函数
  24. --对象的子类型不能覆写对象的MAPORDER函数

--我们来看下多态
--创建基类型

  1. create or replace type ma_product is object (
  2. product_id number,
  3. product_name varchar2(100),
  4. product_price number,
  5. not instantiable member procedure show_discount
  6. ) not instantiable not final
  7. ;
  8.  
  9. --创建子类型
  10. create or replace type ma_book under ma_product
  11. (
  12. book_author varchar2(100),
  13. book_pages number,
  14. constructor function ma_book(product_id number,
  15. product_name varchar2,
  16. product_price number,
  17. book_author varchar2,
  18. book_pages number) return self as result,
  19.  
  20. overriding member procedure show_discount
  21. )
  22. instantiable not final;
  23.  
  24. create or replace type body ma_book is
  25.  
  26. constructor function ma_book(product_id number,
  27. product_name varchar2,
  28. product_price number,
  29. book_author varchar2,
  30. book_pages number) return self as result is
  31.  
  32. begin
  33. self.product_id := product_id;
  34. self.product_name := product_name;
  35. self.product_price := product_price;
  36. self.book_author := book_author;
  37. self.book_pages := book_pages;
  38.  
  39. return;
  40. end ma_book;
  41.  
  42. overriding member procedure show_discount is
  43.  
  44. begin
  45. dbms_output.put_line(self.product_name || ' 作者是' || self.book_author ||
  46. ',共' || self.book_pages || '页');
  47.  
  48. end show_discount;
  49. end;
  50. /
  51.  
  52. --创建子类型
  53. create or replace type ma_computer under ma_product
  54. (
  55. cpu_size number,
  56. brand varchar2(100),
  57. constructor function ma_computer(product_id number,
  58. product_name varchar2,
  59. product_price number,
  60. brand varchar2,
  61. cpu_size number)
  62. return self as result,
  63.  
  64. overriding member procedure show_discount
  65. )
  66. instantiable not final;
  67.  
  68. create or replace type body ma_computer is
  69.  
  70. constructor function ma_computer(product_id number,
  71. product_name varchar2,
  72. product_price number,
  73. brand varchar2,
  74. cpu_size number)
  75. return self as result is
  76.  
  77. begin
  78. self.product_id := product_id;
  79. self.product_name := product_name;
  80. self.product_price := product_price;
  81. self.brand := brand;
  82. self.cpu_size := cpu_size;
  83.  
  84. return;
  85. end ma_computer;
  86.  
  87. overriding member procedure show_discount is
  88.  
  89. begin
  90. dbms_output.put_line(self.product_name || ' 品牌是' || self.brand ||
  91. ',CPU大小' || self.cpu_size || 'M');
  92.  
  93. end show_discount;
  94. end;
  95. /
  96.  
  97. declare
  98. type list_t is table of ma_product;
  99. product_list list_t;
  100. v_product1 ma_book := ma_book(1, 'plsql实战训练', 25, 'testma', 55);
  101. v_product2 ma_book := ma_book(1, 'plsql实战训练2', 30, 'testma12', 56);
  102. v_product3 ma_computer := ma_computer(1,
  103. '联想笔记本',
  104. 3000,
  105. '联想',
  106. 1024);
  107. v_product4 ma_computer := ma_computer(1,
  108. '清华同方笔记本',
  109. 1999,
  110. '清华同方',
  111. 2048);
  112.  
  113. begin
  114.  
  115. product_list := list_t(v_product1, v_product3, v_product2, v_product4);
  116. for i in 1 .. product_list.count loop
  117. product_list(i) .show_discount();
  118. end loop;
  119. end;
  120. /

--对象集合

--对象类型和集合对象类型之间的唯一区别是,对象只保存单个对象类型,而集合
--保存一个对象类型数组或嵌套表

  1. ma_order_items
  2. create or replace type order_item is object
  3. ( order_id varchar2(32),
  4. product_no number,
  5. product_name varchar2(100),
  6. product_size varchar2(20),
  7. product_num number ,
  8. product_ori_price number ,
  9. product_new_price number
  10. );
  11.  
  12. declare
  13. v order_item := order_item('','','','','','','');--不能使用ORDER_ITEM()进行初始化
  14. begin
  15. v.order_id := sys_guid();
  16. dbms_output.put_line(v.order_id);
  17. end;
  18. /
  19. create or replace type order_item_table is table of order_item;
  20.  
  21. create or replace type order_objects is object
  22. (
  23. order_table order_item_table,
  24. constructor function order_objects(order_table order_item_table)
  25. return self as result,
  26. constructor function order_objects return self as result,
  27. member function get_size return number,
  28. member function get_table return order_item_table,
  29. static function get_order_items(i_low number, i_high number)
  30. return order_item_table
  31. )
  32. instantiable not final;
  33.  
  34. create or replace type body order_objects is
  35. constructor function order_objects(order_table order_item_table)
  36. return self as result is
  37. begin
  38. self.order_table := order_table;
  39. return;
  40. end order_objects;
  41.  
  42. constructor function order_objects return self as result is
  43.  
  44. cursor cur_item is
  45. select * from ma_order_items;
  46. c number := 1;
  47. v_item order_item;
  48. begin
  49. self.order_table := order_item_table();
  50. for v in cur_item loop
  51.  
  52. v_item := order_item(v.ID_MA_ORDERS,
  53. v.product_no,
  54. v.product_name,
  55. v.product_size,
  56. v.product_num,
  57. v.product_ori_price,
  58. v.product_new_price);
  59. self.order_table.extend;
  60. self.order_table(c) := v_item;
  61. c := c + 1;
  62. end loop;
  63. return;
  64.  
  65. end order_objects;
  66. member function get_size return number is
  67.  
  68. begin
  69. return self.order_table.count;
  70. end get_size;
  71.  
  72. member function get_table return order_item_table is
  73. begin
  74. return self.order_table;
  75. end get_table;
  76.  
  77. static function get_order_items(i_low number, i_high number)
  78. return order_item_table is
  79. cursor cur_item is
  80. select *
  81. from ma_order_items t
  82. where t.product_no between i_low and i_high;
  83. c number := 1;
  84. v_item order_item;
  85. v_order_table order_item_table;
  86. begin
  87. v_order_table := order_item_table();
  88. for v in cur_item loop
  89.  
  90. v_item := order_item(v.ID_MA_ORDERS,
  91. v.product_no,
  92. v.product_name,
  93. v.product_size,
  94. v.product_num,
  95. v.product_ori_price,
  96. v.product_new_price);
  97. v_order_table.extend;
  98. v_order_table(c) := v_item;
  99. c := c + 1;
  100. end loop;
  101. return v_order_table;
  102. end get_order_items;
  103. end;
  104. /
  105.  
  106. select * from table(order_objects().get_table());

---对象表

--在ORACLE里,可以把对象保存到数据库中

  1. create table product_objects of ma_product
  2. (constraint pk_ma_product primary key(product_id));
  3.  
  4. --这个语句创建了一个叫做ma_product的对象表,每一行都是一个ma_product对象
  5. --一般来说,对象的每个属性都对应着表中的一列
  6. select * from product_objects ;
  1. --需注意的是ma_product是不可实例化的,这个表中的每一行实际是类似于ma_bookma_computer的子类型
  2. insert into product_objects values (ma_book(1, 'plsql实战训练', 25, 'testma', 55));
  3. insert into product_objects values (ma_book(2, 'plsql实战训练2', 30, 'testma12', 56));
  4. insert into product_objects values (ma_computer(3,'联想笔记本',3000,'联想',1024));
  5. insert into product_objects values (ma_computer(4,'清华同方笔记本',1999,'清华同方',2048));
  6.  
  7. select * from product_objects;

---所属子类型的属性哪去了呢?
--oracle 把子类型专有的属性放在了product_objects的隐藏列中
--从对象编程角度来看,这种方法既保留了商品的抽象性,有能够在需要的时候暴露子类型的而外信息

--对象标识符
--ORALE可以用主键值或这系统生成的值(SYS_NC_OID$)来产生对象标识符

--系统生成的OID:不透明,可以数据库全局唯一,不可变;

  1. ---VALUE函数
  2. --从数据库中提取一个对象,可以使用VALUE函数
  3. select value(p) from product_objects p ;
  4.  
  5. --value只接受一个参数,这个参数必须是当前FROM子句中的表别名,返回的是一个用于定义表的类型对象;
  6.  
  7. declare
  8. v_product ma_product;
  9. cursor cur_product is
  10. select value(p) from product_objects p;
  11.  
  12. begin
  13. open cur_product;
  14. loop
  15. fetch cur_product
  16. into v_product;
  17. exit when cur_product%notfound;
  18. v_product.show_discount();
  19. end loop;
  20. end;
  21. /
  22. --还可以直接访问属于基类的属性
  23. select value(p).product_id from product_objects p ;
  24. --能否直接访问子类型的属性呢?
  25. select value(p).book_author from product_objects p ;
  26.  
  27. ---如果一个对象表基于的对象类型没有子类,就可以利用传统的SQL语句对于所有的列执行选择,插入,更新,删除操作
  28. select product_id from product_objects p ;
  29. update product_objects p
  30. set p.product_id = 6
  31. where p.product_id = 1;
  32. --对于那些因为是子类型而被当作隐藏的列,就不能使用传统的关系DML操作,,必须使用对象DML方法
  33. update product_objects p
  34. set p = ma_book(1, 'plsql实战训练', 25, 'testma', 55)
  35. where p.product_id = 6;
  36. --要想更新某个子类型特有列值,唯一的好办法是更新整个对象

--TREAT 函数

--怎样去访问对象表中子类型的特有属性呢?

  1. DECLARE
  2. V_BOOK ma_book;
  3. V_PRODUCT ma_product := ma_book(1, 'plsql实战训练', 25, 'testma', 55);
  4. BEGIN
  5. v_book := treat(v_product as ma_book);---从父类型向子类型转换,向下转换或者缩小
  6. v_book.show_discount();
  7. END;
  8. /
  9.  
  10. --TREAT函数的语法
  11. treat(object_instance as subtype)[.{attribute|method(args...)}];
  12. --怎么去感知某个父类型是某个子类型呢?
  13. OBJECT IS OF ([ONLY] TYPENAME)
  14. --ONLY:如果一个对象属于指定的类型或者任意一个子类型,不带ONLY的话,返回TRUE
  15. --如果使用了ONLY,这个表达式不会检查子类型,只有对象完全匹配时才返回TRUE
  16.  
  17. declare
  18. v_product ma_product;
  19. cursor cur_product is
  20. select value(p) product from product_objects p;
  21. begin
  22.  
  23. for v in cur_product loop
  24. case
  25. when v.product is of(ma_book) then
  26. dbms_output.put_line(treat(v.product as ma_book).book_author);
  27.  
  28. when v.product is of(ma_computer) then
  29. dbms_output.put_line(treat(v.product as ma_computer).brand);
  30. else
  31. dbms_output.put_line('unknown object');
  32. end case;
  33. end loop;
  34.  
  35. end;
  36. /
  37.  
  38. ---如果想修改MA_PRODUCT,怎么办
  39. --比如删除对象类型
  40. drop type ma_product validate;
  41.  
  42. drop type typename [force | validate]
  43. --在MA_PRODUCT新增一个属性?
  44. alter type ma_product add attribute publication_date date
  45. cascade including table data ;
  46. --删除类型ma_book的方法
  47. alter type ma_book drop constructor function ma_book(product_id number,
  48. product_name varchar2,
  49. product_price number,
  50. book_author varchar2,
  51. book_pages number) return self as result cascade;

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

  1. declare
  2. p_numbers varchar2(100) :='tydbser';
  3. type t_table is table of char index by pls_integer;
  4. v_tab t_table;
  5. v_tmp char(1);
  6. Result varchar2(100);
  7. begin
  8. for i in 1 .. nvl(length(p_numbers), 0) loop
  9. v_tab(i) := substr(p_numbers, i, 1);
  10. end loop;
  11.  
  12. for p in 1 .. nvl(length(p_numbers), 0) - 1 loop
  13. for q in reverse p .. nvl(length(p_numbers), 0)-1 loop ---一定要从冒泡轨迹的起点开始比较。
  14. if v_tab(q) <= v_tab(q+1) then
  15. v_tmp := v_tab(q);
  16. v_tab(q) := v_tab(q+1);
  17. v_tab(q+1) := v_tmp;
  18. end if;
  19. end loop;
  20. end loop;
  21.  
  22. for i in 1 .. nvl(length(p_numbers), 0) loop
  23. Result := Result || v_tab(i);
  24. end loop;
  25.  
  26. dbms_output.put_line(Result);
  27. end ;
  28.  
  29. declare
  30. v_data1 map_comp := map_comp('a');
  31. v_data2 map_comp := map_comp('a');
  32. v_data3 map_comp := map_comp('b');
  33. v_data4 map_comp;
  34.  
  35. begin
  36. if v_data1 = v_data2 then
  37. dbms_output.put_line('equal');
  38. else
  39. dbms_output.put_line('not equal');
  40. end if;
  41.  
  42. if v_data1 = v_data3 then
  43. dbms_output.put_line('equal');
  44. else
  45. dbms_output.put_line('not equal');
  46. end if;
  47.  
  48. if v_data1 <= v_data2 then
  49. v_data4 := v_data1;
  50. v_data1 := v_data2;
  51. v_data2:= v_data4;
  52. -- dbms_output.put_line(v_data1);
  53. -- dbms_output.put_line(v_data2);
  54. -- dbms_output.put_line(v_data4);
  55. end if;
  56.  
  57. end;
  58. /
  59.  
  60. --定义对象
  61. create or replace type bhgx_obj is object
  62. (
  63. letter varchar2(1),
  64. constructor function bhgx_obj return self as result,
  65. constructor function bhgx_obj(letter varchar2) return self as result,
  66. member function toString return varchar2,
  67. order member function equal(v_obj bhgx_obj) return number
  68. ) instantiable not final;
  69.  
  70. CREATE OR REPLACE TYPE let_obj IS TABLE OF bhgx_obj;
  71.  
  72. --创建对象体
  73. create or replace type body bhgx_obj as
  74. --默认构造方法
  75. constructor function bhgx_obj return self as result is
  76. v_obj bhgx_obj := bhgx_obj('');
  77. begin
  78. self := v_obj;
  79. return;
  80. end bhgx_obj;
  81. --重写构造方法
  82. constructor function bhgx_obj(letter varchar2) return self as result is
  83. begin
  84. self.letter := letter;
  85. return; -- 返回一个副本,即对象实例的当前内存引用
  86. end bhgx_obj;
  87. --成员函数
  88. member function toString return varchar2 is
  89. begin
  90. return self.letter ;
  91. end toString;
  92. order member function equal(v_obj bhgx_obj) return number is
  93. begin
  94. if self.letter > v_obj.letter then
  95. return 1 ;
  96. elsif self.letter < v_obj.letter then
  97. return -1 ;
  98. elsif self.letter = v_obj.letter then
  99. return 0 ;
  100. else
  101. return 0 ;
  102. end if;
  103. end equal;
  104. end;
  105. --创建包
  106. create or replace package pkg_data_order is
  107. function order_letter(v_l let_obj) return let_obj ;
  108. end pkg_data_order;
  109. --创建包体
  110. CREATE OR REPLACE PACKAGE BODY pkg_data_order IS
  111. function order_letter(v_l let_obj)
  112. return let_obj as
  113. v_t bhgx_obj;
  114. v_letts let_obj:=v_l;
  115. begin
  116. FOR i IN 1..v_letts.COUNT LOOP
  117. FOR j IN 1..(v_letts.COUNT-i) LOOP
  118. if v_letts(j).equal(v_letts(j+1))>0 then
  119. v_t := v_letts(j) ;
  120. v_letts(j) := v_letts(j+1);
  121. v_letts(j+1) := v_t;
  122. end if;
  123. END LOOP;
  124. END LOOP;
  125. return v_letts ;
  126. end;
  127. end pkg_data_order;
  128.  
  129. --调用
  130. declare
  131. v_p let_obj:=let_obj() ;
  132. begin
  133. v_p.extend ;
  134. v_p(1):=bhgx_obj('z');
  135. v_p.extend ;
  136. v_p(2):=bhgx_obj('b');
  137. v_p.extend ;
  138. v_p(3):=bhgx_obj('d');
  139. v_p.extend ;
  140. v_p(4):=bhgx_obj('m');
  141. v_p.extend ;
  142. v_p(5):=bhgx_obj('a');
  143. v_p.extend ;
  144. v_p(6):=bhgx_obj('k');
  145. v_p.extend ;
  146. v_p(7):=bhgx_obj('c');
  147. v_p.extend ;
  148. v_p(8):=bhgx_obj('q');
  149.  
  150. v_p := pkg_data_order.order_letter(v_p) ;
  151. FOR i IN 1..v_p.COUNT LOOP
  152. dbms_output.put_line(v_p(i).toString());
  153. END LOOP;
  154. end;
  155.  
  156. --------
  157. CREATE OR REPLACE procedure test_bubble(str IN VARCHAR2) IS
  158. type v_type is varray(1000) of varchar2(100);
  159. var v_type;
  160. temp varchar2(100);
  161. flag boolean;
  162. results VARCHAR2(4000);
  163. BEGIN
  164. select substr(str,level,1) bulk collect into var
  165. from dual connect by level <=length(str);
  166. <<outer_scope>>
  167. for i in 1 .. var.count-1 loop
  168. flag := false;
  169. for j in reverse i .. var.count-1 loop
  170. if var(j+1) < var(j) then
  171. temp := var(j+1);
  172. var(j+1) := var(j);
  173. var(j) := temp;
  174. flag := true;
  175. end if;
  176. end loop;
  177. if (not flag) then
  178. exit outer_scope;
  179. end if;
  180. end loop;
  181. for i in var.first .. var.last loop
  182. results :=concat(results,var(i));
  183. end loop;
  184. dbms_output.put_line('out_results='||results);
  185. END test_bubble;
  186.  
  187. --测试过程
  188. declare
  189. begin
  190. test_bubble('zlmbwacgiofrskne');
  191. end;
  192. -----------
  193.  
  194. create or replace type map_comp is object(
  195. cmp_data varchar2(1),
  196. constructor function map_comp(cmp_data varchar2) return self as result,
  197. map member function equal return varchar2,
  198. member function to_string return varchar2
  199. )instantiable not final;
  200.  
  201. create or replace type body map_comp is
  202. constructor function map_comp(cmp_data varchar2) return self as result is
  203. begin
  204. self.cmp_data := cmp_data;
  205. return;
  206. end map_comp;
  207. map member function equal return varchar2 is
  208. begin
  209. return self.cmp_data;
  210. end equal;
  211. member function to_string return varchar2 is
  212. begin
  213. return self.cmp_data;
  214. end to_string;
  215. end;
  216.  
  217. --赋值和排序
  218. declare
  219. type ind_obj_type is table of map_comp index by pls_integer;
  220. v_ind_obj ind_obj_type;
  221. v_aaa map_comp;
  222. begin
  223. --初始化,随机赋值
  224. for i in 1 .. 15 loop
  225. v_ind_obj(i) := map_comp(chr(97 + dbms_random.value(1, 25)));
  226. end loop;
  227. --打印排序前对象中的字母
  228. dbms_output.put('排序前: ');
  229. for i in 1 .. v_ind_obj.count loop
  230. dbms_output.put(v_ind_obj(i).to_string() || ' ');
  231. end loop;
  232. dbms_output.put_line('');
  233. --冒泡排序
  234. for i in 1 .. v_ind_obj.count loop
  235. for j in i + 1 .. v_ind_obj.count loop
  236. if v_ind_obj(i) > v_ind_obj(j) then
  237. v_aaa := v_ind_obj(j);
  238. v_ind_obj(j) := v_ind_obj(i);
  239. v_ind_obj(i) := v_aaa;
  240. end if;
  241. end loop;
  242. end loop;
  243. --打印排序后
  244. dbms_output.put('排序后: ');
  245. for i in 1 .. v_ind_obj.count loop
  246. dbms_output.put(v_ind_obj(i).to_string() || ' ');
  247. end loop;
  248. dbms_output.put_line('');
  249. exception
  250. when others then
  251. dbms_output.put_line(sqlerrm);
  252. end;

PL/SQL 训练09--面向对象的更多相关文章

  1. PL/SQL 训练13--plsql 优化

    --数据缓存技术 --PGA和SGA---SGA:系统全局区域--PGA:Process Global Area是为每个连接到Oracle的用户进程保留的内存. ---PLSQL从PGA获取信息的速度 ...

  2. PL/SQL 训练12--动态sql和绑定变量

    --什么是动态SQL?动态PL/SQL--动态SQL是指在运行时刻才构建执行的SQL语句--动态PL/SQL是指整个PL/SQL代码块都是动态构建,然后再编译执行 --动态SQL来可以用来干什么? - ...

  3. PL/SQL 训练11--包

    --所谓包,就是把一组PL/SQL的代码元素组织在一个命名空间下.--一种可以把程序或者其他的PL/SQL元素比如游标.类型.变量的组织结构在一起的结构(包括逻辑结构和物理结构)--包提供了非常重要的 ...

  4. PL/SQL 训练10--io及文件操作

    多数程序只需要通过SQL和底层数据库进行交互--有些情况,不可避免的还是会有一些场景,需要从PL/SQL给外部环境发送信息--或是从一些外部的源读入信息 --这节课介绍下面这些内置包 dbms_out ...

  5. PL/SQL 训练08--触发器

    --什么是触发器呢?--一触即发,某个事件发生时,执行的程序块?--数据库触发器是一个当数据库发生某种事件时作为对这个事件的响应而执行的一个被命名的程序单元 --适合场景--对表的修改做验证--数据库 ...

  6. PL/SQL 训练05--游标

    --隐式游标--通过一个简单的SELECT ...INTO 语句提取一行数据,并放在一个局部变量中,最简单获取数据的途径 --显示游标--可以在声明单元明确的声明一个查询,这样可以在一个或多个程序中打 ...

  7. PL/SQL 训练04--事务

    --pl/sql通过SQL和ORACLE数据库紧密的整合在一起--在pl/sql中可以执行任何操作语句(DML语句),包括INSERT,UPDATE,DELETE,MERGE,也包括查询语句--可否执 ...

  8. PL/SQL 训练03 --异常

    --程序员在开发的时候,经常天真的认为这个世界是完美的,用户如同自己般聪明,总能按照自己设想的方式--操作系统输入数据.但残酷的事实告诉我们,这是不可能的事情,用户总会跟我们相反的方式操作系统--于是 ...

  9. PL/SQL 训练02--集合数组

    1. 请列举关联数组.嵌套表.VARRAY三种集合类型的区别区别:1 关联数组只能在plsql中使用,嵌套表,varray可用于sql中,数据库表中的列2 嵌套表,varray必须在使用的时候初始化, ...

  10. PL/SQL 训练01--基础介绍

    --开始介绍变量之前,我们先看下怎么在PLSQL写程序,如下我们写了一个块 declare --声明部分,声明变量 v_name ) :='hello world'; begin --执行区域 dbm ...

随机推荐

  1. 使用maven时报错An error occurred while filtering resources

    解决办法:右键项目-->maven-->update project   .

  2. ubuntu16.04 运行elasticfusion

    环境:Ubuntu16.04 64bit    Kinect V1 XBOX 360 1.安装OpenNI2并试运行 https://fredfire1.wordpress.com/2016/09/2 ...

  3. Load事件

    Load事件 在 窗体完全呈现之后 被 触发 如下伪代码: void  ShowWindows { .....//显示父容器 .....//显示子容器 .....//显示控件 //至此,窗体完全呈现 ...

  4. 51nod 1486

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1486 1486 大大走格子 题目来源: CodeForces 基准时间限 ...

  5. HTTP metadata数据

    信息元位置 信息元名称 信息元ID 信息元描述 1 MetadataVersion 5000 Metadata版本号 当前版本号为1.0 2 MetadataID 1019 MetadataID 3 ...

  6. JS兼容性汇总

    1.  Frame  (1)问题:在IE中可以用window.top.frameId和window.top.frameName来得到该Frame所代表的Window,Firefox中只能用window ...

  7. OC-存档

    Δ一.   .plist文件 .plist文件是一个属性字典数组的一个文件: .plist文件可以用来存储:字典.数组.字符串等对象数据,可以混搭存储 [注]iOS开发中,plist文件一般用于app ...

  8. Visual Studio 2008常见问题

    1.asp.net在什么软件上运行?学习asp往往需要测试asp程序,电脑不能直接测试,需要装IIS才能运行,但装IIS要么需要安装盘,要么需要安装包,而且设置也很复搜索杂.这里给大学推荐两个替代II ...

  9. 怎么把openrety 里边的 table 优雅的打印出来

    1.安装 loarocks 库以后 2.安装 Penlight 插件 3.如下图所示 4.利用dump 函数优雅的打印 table

  10. HihoCoder 1044 01-string 贪心

    1144 : 01串 时间限制:7000ms 单点时限:1000ms 内存限制:256MB 描述 给定两个整数n和m,求是否存在恰好包含n个0和m个1的01串S,使得S中不存在子串"001& ...