`

精通Oracle10编程SQL(8)使用复合数据类型

阅读更多
/*
 *使用复合数据类型
 */

--PL/SQL记录
--定义PL/SQL记录
--自定义PL/SQL记录
DECLARE
  TYPE emp_record_type IS RECORD(
     name emp.ename%TYPE,
     salary emp.sal%TYPE,
     dno emp.deptno%TYPE
  );
  emp_record emp_record_type;
  ...
  
--使用PL/SQL记录
--在SELECT INTO语句中使用PL/SQL记录
--在SELECT INTO语句中使用记录变量
DECLARE
  TYPE emp_record_type IS RECORD(
    name emp.ename%TYPE,
    salary emp.sal%TYPE,
    dno emp.deptno%TYPE);
  emp_record emp_record_type;
BEGIN
  SELECT ename,sal,deptno into emp_record
  from emp where empno=&no;
  dbms_output.put_line(emp_record.name);
end;

--在SELECT INTO语句中使用记录成员
DECLARE
  type emp_record_type is record(
    name emp.ename%TYPE,
    salary emp.sal%TYPE,
    dno emp.deptno%TYPE);
  emp_record emp_record_type;
BEGIN
  SELECT ename,sal into emp_record.name,emp_record.salary
  from emp where empno=&no;
  dbms_output.put_line(emp_record.name);
end;

--在INSERT语句中使用PL/SQL记录
--在VALUES子句中使用记录变量
DECLARE
  dept_record dept%ROWTYPE;
BEGIN
  dept_record.deptno:=51;
  dept_record.dname:='ADMINISTRATOR';
  dept_record.loc:='BEIJING';
  insert into dept values dept_record;
END;

SELECT * FROM dept;

--在VALUES子句中使用记录成员
declare
  dept_record dept%ROWTYPE;
begin
  dept_record.deptno:=60;
  dept_record.dname:='SALES';
  INSERT INTO dept(deptno,dname) values
  (dept_record.deptno,dept_record.dname);
end;

--在UPDATE语句中使用PL/SQL记录
--在SET子句中使用记录变量
DECLARE
  dept_record dept%ROWTYPE;
begin
  dept_record.deptno:=60;
  dept_record.dname:='SALES';
  dept_record.loc:='SHANGHAI';
  update dept set row=dept_record where deptno=60;
end;

select * from dept;

--在SET子句中使用记录成员
DECLARE
  dept_record dept%ROWTYPE;
BEGIN
  dept_record.loc:='GUANGZHOU';
  UPDATE dept set loc=dept_record.loc where deptno=50;
end;

--在DELETE语句中使用PL/SQL记录
DECLARE
  dept_record dept%ROWTYPE;
begin
  dept_record.deptno:=50;
  delete from dept where deptno=dept_record.deptno;
end;

select * from dept;

--PL/SQL集合
--索引表
--在索引表中使用BINARY_INTEGER和PLS_INTEGER
DECLARE
  TYPE ename_table_type IS TABLE OF emp.ename%TYPE
    INDEX BY BINARY_INTEGER;
  ename_table ename_table_type;
BEGIN
  SELECT ename into ename_table(-1) from emp
    where empno=&no;
  dbms_output.put_line('雇员名:'||ename_table(-1));
END;

SELECT * FROM EMP;  
  
--在索引表中使用VARCHAR2
DECLARE
  TYPE area_table_type IS TABLE OF NUMBER
    INDEX BY VARCHAR2(10);
  area_table area_table_type;
BEGIN
  area_table('北京'):=1;
  area_table('上海'):=2;
  area_table('广州'):=3;
  dbms_output.put_line('第一个元素:'||area_table.first);
  dbms_output.put_line('最后一个元素:'||area_table.last);
END;

--嵌套表
--在PL/SQL块中使用嵌套表
--其中,ename_table_type为嵌套表类型,而ename_table_type()是其构造方法
DECLARE
  type ename_table_type is table of emp.ename%TYPE;
  ename_table ename_table_type;
BEGIN
  ename_table:=ename_table_type('MARY','MARY','MARY');
  select ename into ename_table(2) from emp
    where empno=&no;
  dbms_output.put_line('雇员名:'||ename_table(2));
END;

--在表列中使用嵌套表
create type phone_type is table of varchar2(20);

create table employeeTest(
  id number(4),name varchar2(10),sal number(6,2),
  phone phone_type
)nested table phone store as phone_table;

--在PL/SQL块中为嵌套表列插入数据
BEGIN
  INSERT INTO employeeTest values(1,'SCOTT',800,
  phone_type('0739-12121212','13800001111'));
END;

select * from employeeTest;

--在PL/SQL块中检索嵌套表列的数据
DECLARE
   phone_table phone_type;
BEGIN
   SELECT phone into phone_table from employeeTest where id=1;
   for i IN 1..phone_table.count loop
     dbms_output.put_line('电话号码:'||phone_table(i));
   end loop;
end;

--在PL/SQL块中更新嵌套表列的数据
DECLARE
  phone_table phone_type:=phone_type('0471-3456788','13825252525','0471-2233066','13056278568');
BEGIN
  UPDATE employeeTest set phone=phone_table where id=1;
END;

--变长数组(VARRAY)
--在PL/SQL块中使用VARRY
--当在PL/SQL块中使用VARRAY变量时,必须首先使用其构造方法来初始化VARRAY变量,然后才能在PL/SQL块内引用VARRAY元素
DECLARE
   TYPE ename_table_type IS VARRAY(20) OF emp.ename%TYPE;
   ename_table ename_table_type:=ename_table_type('mary');
BEGIN
   SELECT ename into ename_table(1) from emp where empno=&no;
   dbms_output.put_line('雇员名:'||ename_table(1));
END;

--在表列中使用VARRAY
create type phone_type is varray(20) of varchar2(20);

create table employee(
  id number(4),name varchar2(10),
  sal number(6,2),phone phone_type);


--PL/SQL记录表
--处理多行多列数据
DECLARE
   type emp_table_type is table of emp%ROWTYPE INDEX BY binary_integer;
   emp_table emp_table_type;
BEGIN
   select * into emp_table(1) from emp
   where empno=&no;
   dbms_output.put_line('雇员姓名:'||emp_table(1).ename);
   dbms_output.put_line('雇员工资:'||emp_table(1).sal);
END;

--多级集合
--在PL/SQL块中使用多级VARRAY
DECLARE
  --定义一维VARRAY
  TYPE al_varray_type IS VARRAY(10) of int;
  --定义二维VARRAY集合
  TYPE nal_varray_type is varray(10) of al_varray_type;
  --初始化二维集合变量
  nvl nal_varray_type:=nal_varray_type(
      al_varray_type(58,100,102),
      al_varray_type(55,6,73),
      al_varray_type(2,4));
BEGIN
  dbms_output.put_line('显示二维数组所有元素');
  for i in 1..nvl.count loop
     for j in 1..nvl(i).count loop
        dbms_output.put_line('nvl('||i||','||j||')='||nvl(i)(j));
     end loop;
  end loop;
END;

--在PL/SQL块中使用多级嵌套表
DECLARE
  --定义一维嵌套表
  TYPE al_table_type is table of int;
  --定义二维嵌套表集合
  TYPE nal_table_type is table of al_table_type;
  --初始化二维集合变量
  nvl nal_table_type:=nal_table_type(
      al_table_type(2,4,78),
      al_table_type(5,73));
BEGIN
   DBMS_OUTPUT.put_line('显示二维数组所有元素');
   for i in 1..nvl.count loop
      for j in 1..nvl(i).count loop
          dbms_output.put_line('nvl('||i||','||j||')='||nvl(i)(j));
      end loop;
    end loop;
END;

--在PL/SQL块中使用多级索引表
DECLARE
   --定义一维table
   TYPE al_table_type IS TABLE OF INT INDEX BY BINARY_INTEGER;
   --定义二维table集合
   TYPE nal_table_type is TABLE OF al_table_type index by BINARY_INTEGER;
   nvl nal_table_type;
BEGIN
   nvl(1)(1):=10;
   nvl(1)(2):=5;
   nvl(1)(3):=57;
   nvl(2)(1):=100;
   nvl(2)(2):=50;
   DBMS_OUTPUT.put_line('显示二维数组所有元素');
   for i in 1..nvl.count loop
      for j in 1..nvl(i).count loop
          dbms_output.put_line('nvl('||i||','||j||')='||nvl(i)(j));
      end loop;
    end loop;
END;

--集合方法
--集合方法是ORACLE所提供的用于操纵集合变量的内置函数或过程,其中EXISTS,COUNT,LIMIT,FIRST,NEXT,PRIOR和NEXT是函数,而EXTEND,TRIM和DELETE则是过程。
--集合方法的调用语法如下:collection_name.method_name[(parameters)]
--集合方法只能在PL/SQL语句中使用,而不能在SQL语句中调用。另外集合方法EXTEND和TRIM只适用于嵌套表和VARRAY,而不适用于索引表。

--EXISTS
DECLARE
  TYPE ename_table_type is table of emp.ename%TYPE;
  ename_table ename_table_type;
BEGIN
  if ename_table.EXISTS(1) THEN
     ename_table(1):='SCOTT';
  else
     dbms_output.put_line('必须初始化集合元素');
  end if;
END;

--COUNT
--返回当前集合变量中的元素总个数,如果集合元素存在数值,则统计结果会包含该元素,如果集合元素为NULL,则统计结果不会包含该元素
DECLARE
  type ename_table_type is table of emp.ename%TYPE INDEX BY BINARY_INTEGER;
  ename_table ename_table_type;
BEGIN
  ename_table(-5):='SCOTT';
  ename_table(0):='SMITH';
  ename_table(5):='MARY';
  ename_table(10):='BLAKE';
  dbms_output.put_line('集合元素总个数:'||ename_table.count);
END;

--LIMIT
--返回集合元素的最大个数,因为嵌套表和索引表的元素个数没有限制,所以调用该方法会返回NULL,而对于VARRAY来说,该方法会返回VARRAY所允许的最大元素个数
DECLARE
  type ename_table_type is varray(20) of emp.ename%TYPE;
  ename_table ename_table_type:=ename_table_type('mary');
BEGIN
  DBMS_OUTPUT.PUT_LINE('集合元素的最大个数:' || ename_table.limit);
END;

--FIRST和LAST
--FIRST返回集合变量第一个元素的下标,而LAST方法则用于返回集合变量最后一个元素的下标
DECLARE
  type ename_table_type is table of emp.ename%TYPE INDEX BY binary_integer;
  ename_table ename_table_type;
BEGIN
  ename_table(-5):='SCOTT';
  ename_table(0):='SMITH';
  ename_table(5):='MARY';
  ename_table(10):='BLAKE';
  dbms_output.put_line('第一个元素:'||ename_table.first);
  dbms_output.put_line('最后一个元素:'||ename_table.last);
END;

--PRIOR和NEXT
--PRIOR用于返回当前集合元素的前一个元素的下标,而NEXT方法则用于返回当前集合元素的后一个元素的下标
DECLARE
  type ename_table_type is table of emp.ename%TYPE INDEX BY binary_integer;
  ename_table ename_table_type;
BEGIN
  ename_table(-5):='SCOTT';
  ename_table(0):='SMITH';
  ename_table(5):='MARY';
  ename_table(10):='BLAKE';
  dbms_output.put_line('元素5的前一个元素:'||ename_table.prior(5));
  dbms_output.put_line('元素5的后一个元素:'||ename_table.next(5));
END;

--EXTEND
--用于扩展集合变量的尺寸,并为它们增加元素,该方法只适用于嵌套表和VARRAY。
--EXTEND:为集合变量添加一个null元素
--EXTEND(n):为集合变量添加n个null元素
--EXTEND(n,i):为集合变量添加n个元素(元素值与第i个元素相同)
DECLARE
  TYPE ename_table_type is array(20) of varchar2(10);
  ename_table ename_table_type;
BEGIN
  ename_table:=ename_table_type('MARY');
  ename_table.extend(5,1);
  dbms_output.put_line('元素总个数:'||ename_table.count);
END;

--TRIM
--用于从集合尾部删除元素,它有TRIM和TRIM(n)两种调用格式
--其中TRIM用于从集合尾部删除一个元素,而TRIM(n)则用于从集合尾部删除n个元素。
--该方法只适用于嵌套表和VARRAY
DECLARE
   type ename_table_type is table of varchar2(10);
   ename_table ename_table_type;
BEGIN
   ename_table:=ename_table_type('A','A','A','A','A');
   ename_table.trim(2);
   dbms_output.put_line('元素总个数:'||ename_table.count);
END;

--DELETE
--用于删除集合元素,该方法只适用于嵌套表和索引表,而不适用于VARRAY
--DELETE:删除集合变量的所有元素
--DELETE(n):删除集合变量的第n个元素
--DELETE(m,n):删除集合变量中从m到n之间的所有元素
DECLARE
  TYPE ename_table_type is table of emp.ename%TYPE INDEX BY BINARY_INTEGER;
  ename_table ename_table_type;
BEGIN
  ename_table(-5):='SCOTT';
  ename_table(1):='SMITH';
  ename_table(5):='MARY';
  ename_table(10):='BLAKE';
  ename_table.delete(5);
  dbms_output.put_line('元素总个数:'||ename_table.count);
END;


--集合赋值
--通过执行INSERT,UPDATE,FETCH,SELECT,赋值语句,用户可以将一个集合的数据赋值给另一个集合。
--SET操作符用于取消嵌套表中的重复值
--MULTISET UNION用于取得两个嵌套表的并集(带有DISTINCT操作符可以取消重复结果)
--MULTISET INTERSECT用于取得两个嵌套表的交集
--MULTISET EXCEPT用于取得两个嵌套表的差集

--将一个集合的数据赋值给另一个集合
--当使用赋值语句(:=)或SQL语句将源集合中的数据赋值给目标集合时,会自动清除目标集合原有的数据,并将源集合中的数据赋值给该目标集合
--注意:当进行集合赋值时,源集合和目标集合的数据类型必须完全一致。如果集合元素数据类型一致,但集合类型不一致,那也不能进行赋值。
DECLARE
   TYPE name_varray_type is varray(4) of varchar2(10);
   name_array1 name_varray_type;
   name_array2 name_varray_type;
BEGIN
   name_array1:=name_varray_type('SCOTT','SMITH');
   name_array2:=name_varray_type('a','a','a','a');
   dbms_output.put('name_array2的原数据:');
   for i in 1..name_array2.count loop
      dbms_output.put(' '||name_array2(i));
   end loop;
   dbms_output.new_line;
   name_array2:=name_array1;
   dbms_output.put('name_array2的新数据:');
   for i in 1..name_array2.count loop
      dbms_output.put(' '||name_array2(i));
   end loop;
   dbms_output.new_line;
END;

--给集合赋NULL值
DECLARE
  TYPE name_varry_type is varray(4) of varchar2(10);
  name_array name_varry_type;
  name_empty name_varry_type;
BEGIN
  name_array:=name_varry_type('SCOTT','SMITH');
  dbms_output.put_line('name_array的原有元素个数:'||name_array.count);
  name_array:=name_empty;
  if name_array is null then
     dbms_output.put_line('name_array的现有元素个数:0');
  end if;
END;

--使用集合操作符给嵌套表赋值
--使用SET操作符
DECLARE
  type nt_table_type is table of number;
  nt_table nt_table_type:=nt_table_type(2,4,3,1,2);
  result nt_table_type;
BEGIN
  result:=set(nt_table);
  dbms_output.put('result:');
  for i in 1..result.count loop
    dbms_output.put('  '||result(i));
  end loop;
  dbms_output.new_line;
END;

--使用MULTISET UNION操作符
--用于取得两个嵌套表的并集
DECLARE
  TYPE nt_table_type is table of number;
  nt1 nt_table_type:=nt_table_type(1,2,3);
  nt2 nt_table_type:=nt_table_type(3,4,5);
  result nt_table_type;
BEGIN
  result:=nt1 multiset union nt2;
  dbms_output.put('result:');
  for i in 1..result.count loop
     dbms_output.put(' '||result(i));
  end loop;
  dbms_output.new_line;
END;

--使用MULTISET UNION DISTINCT操作符
--取得两个嵌套表的并集,并取消重复结果
DECLARE
  TYPE nt_table_type is table of number;
  nt1 nt_table_type:=nt_table_type(1,2,3);
  nt2 nt_table_type:=nt_table_type(3,4,5);
  result nt_table_type;
BEGIN
  result:=nt1 multiset union distinct nt2;
  dbms_output.put('result:');
  for i in 1..result.count loop
     dbms_output.put(' '||result(i));
  end loop;
  dbms_output.new_line;
END;

--使用MULTISET INTERSECT操作符
--用于取得两个嵌套表的交集
DECLARE
  TYPE nt_table_type is table of number;
  nt1 nt_table_type:=nt_table_type(1,2,3);
  nt2 nt_table_type:=nt_table_type(3,4,5);
  result nt_table_type;
BEGIN
  result:=nt1 multiset intersect nt2;
  dbms_output.put('result:');
  for i in 1..result.count loop
     dbms_output.put(' '||result(i));
  end loop;
  dbms_output.new_line;
END;

--使用MULTISET EXCEPT操作符
--用于取得两个嵌套表的差集
DECLARE
  TYPE nt_table_type is table of number;
  nt1 nt_table_type:=nt_table_type(1,2,3);
  nt2 nt_table_type:=nt_table_type(3,4,5);
  result nt_table_type;
BEGIN
  result:=nt1 multiset except nt2;
  dbms_output.put('result:');
  for i in 1..result.count loop
     dbms_output.put(' '||result(i));
  end loop;
  dbms_output.new_line;
END;


--比较集合
--CARDINALITY用于返回嵌套表变量的元素个数,操作符SUBMULTISET OF用于确定一个嵌套表是否为另一个嵌套表的子集
--MEMBER OF用于检测特定数据是否为嵌套表元素
--IS A SET用于检测嵌套表是否包含重复的元素值
--IS EMPTY用于检测嵌套表是否为NULL

--检测集合是否为NULL
DECLARE
   type name_array_type is varray(3) of varchar2(10);
   name_array name_array_type;
BEGIN
   IF name_array is null then
      dbms_output.put_line('name_array未初始化');
   END IF;
END;

--当检测嵌套表是否为NULL时,不仅可以使用IS NULL操作符,也可以使用IS EMPTY操作符。
--注意,IS EMPTY操作符只适用于嵌套表,而不适用于VARRAY
DECLARE
   TYPE name_table_type is table of varchar2(10);
   name_table name_table_type;
BEGIN
   if name_table is EMPTY then
      dbms_output.put_line('name_table未初始化');
   end if;
END;


--比较嵌套表是否相同
--允许使用比较操作符=和!=检测两个嵌套表变量是否相同
--注意,使用这两个比较符只能比较嵌套表,而不能比较VARRAY和索引表
DECLARE
   TYPE name_table_type is table of varchar2(10);
   name_table1 name_table_type;
   name_table2 name_table_type;
BEGIN
   name_table1:=name_table_type('SCOTT');
   name_table2:=name_table_type('SMITH');
   if name_table1=name_table2 then
      dbms_output.put_line('两个嵌套表完全相同');
   else
      dbms_output.put_line('两个嵌套表数值不同');
   END IF;
END;

--在嵌套表上使用集合操作符
--从ORACLE 10g开始,可以在嵌套表上使用ANSI集合操作符CARDINALITY,MEMBER OF,IS A SET。
--注意,这些操作符只适用于嵌套表,而不适用于VARRAY和索引表

--使用函数CARDINALITY,用于返回嵌套表变量的元素个数
DECLARE
   TYPE nt_table_type is table of number;
   nt1 nt_table_type:=nt_table_type(1,2,3,1);
BEGIN
   dbms_output.put_line('元素个数:'||cardinality(nt1));
END;

--SUBMULTISET OF:确定一个嵌套表是否为另一个嵌套表的子集
DECLARE
   TYPE nt_table_type is table of number;
   nt1 nt_table_type:=nt_table_type(1,2,4);
   nt2 nt_table_type:=nt_table_type(1,2,3,4);
BEGIN
   if nt1 submultiset of nt2 then
      dbms_output.put_line('nt1是nt2的子集');
   end if;
END;

--使用操作符MEMBER OF:检测特定数据是否为嵌套表的元素
DECLARE
   TYPE nt_table_type is table of number;
   nt1 nt_table_type:=nt_table_type(1,2,3,5);
   v1 number:=&v1;
BEGIN
   if v1 member of nt1 then
      dbms_output.put_line(v1||'是nt1的元素');
   else
      dbms_output.put_line(v1||'不是nt1的元素');
   end if;
END;

--使用操作符IS A SET:检测嵌套表是否包含重复的元素值
DECLARE
   TYPE nt_table_type is table of number;
   nt1 nt_table_type:=nt_table_type(1,2,3,5);
BEGIN
   if nt1 is a set then
      dbms_output.put_line('嵌套表nt1无重复值');
   else
      dbms_output.put_line('嵌套表nt1有重复值');
   end if;
END;

--批量绑定
create table demo(
  id number(6) primary key,name varchar2(10)
);

--不使用批量绑定
DECLARE
  TYPE id_table_type is table of number(6) index by binary_integer;
  TYPE name_table_type is table of varchar2(10) index by binary_integer;
  id_table id_table_type;
  name_table name_table_type;
  start_time number(10);
  end_time number(10);
BEGIN
  FOR i in 1..5000 loop
     id_table(i):=i;
     name_table(i):='Name'||to_char(i);
  end loop;
  start_time:=dbms_utility.get_time;
  for i in 1..id_table.count loop
      insert into demo values(id_table(i),name_table(i));
  end loop;
  end_time:=dbms_utility.get_time;
  dbms_output.put_line('总计时间(秒):'||to_char((end_time-start_time)/100));
END;

select * from demo order by id;
delete demo;

--使用批量绑定
DECLARE
  TYPE id_table_type is table of number(6) index by binary_integer;
  TYPE name_table_type is table of varchar2(10) index by binary_integer;
  id_table id_table_type;
  name_table name_table_type;
  start_time number(10);
  end_time number(10);
BEGIN
  FOR i in 1..5000 loop
     id_table(i):=i;
     name_table(i):='Name'||to_char(i);
  end loop;
  start_time:=dbms_utility.get_time;
  forall i in 1..id_table.count
      insert into demo values(id_table(i),name_table(i));
  end_time:=dbms_utility.get_time;
  dbms_output.put_line('总计时间(秒):'||to_char((end_time-start_time)/100));
END;

--批量绑定是使用BULK COLLECT子句和FORALL语句来完成的,其中BULK COLLECT子句用于取得批量数据,该子句只能用于SELECT语句、FETCH语句和DML返回子句中
--而FORALL语句只适用于执行批量的DML操作

--FORALL语句
--在INSERT语句上使用批量绑定
DECLARE
   TYPE id_table_type is TABLE OF NUMBER(6)
      INDEX BY BINARY_INTEGER;
   TYPE name_table_type is TABLE OF VARCHAR2(10)
      index by binary_integer;
   id_table id_table_type;
   name_table name_table_type;
BEGIN
   for i in 1..10 loop
      id_table(i):=i;
      name_table(i):='Name'||to_char(i);
   end loop;
   forall i in 1..id_table.count
      insert into demo values(id_table(i),name_table(i));
End;

select * from demo;

--在UPDATE语句上使用批量绑定
DECLARE
   TYPE id_table_type is TABLE OF NUMBER(6)
      INDEX BY BINARY_INTEGER;
   TYPE name_table_type is TABLE OF VARCHAR2(10)
      index by binary_integer;
   id_table id_table_type;
   name_table name_table_type;
BEGIN
   for i in 1..5 loop
      id_table(i):=i;
      name_table(i):='N'||to_char(i);
   end loop;
   forall i in 1..id_table.count
      update demo set name=name_table(i) where id=id_table(i);
End;

--在DELETE语句上使用批量绑定
DECLARE
   TYPE id_table_type is table of NUMBER(6)
      INDEX BY binary_integer;
   id_table id_table_type;
BEGIN
   for i in 1..3 loop
       id_table(i):=i;
   end loop;
   forall i in 1..id_table.count
      delete from demo where id=id_table(i);
END;

--在FORALL语句中使用部分集合元素
DECLARE
  TYPE id_table_type is table of number(6)
     index by binary_integer;
  id_table id_table_type;
BEGIN
  for i in 1..10 loop
     id_table(i):=11-i;
  end loop;
  forall i in 8..10
     insert into demo(id) values(id_table(i));
END;

SELECT * FROM DEMO;

--在FORALL语句上使用INDICES OF子句
--用于跳过NULL集合元素
DECLARE
  TYPE id_table_type is table of number(6);
  id_table id_table_type;
BEGIN
  id_table:=id_table_type(1,null,3,null,5);
  forall i in indices of id_table
     DELETE FROM demo where id=id_table(i);
END;


--在FORALL语句上使用VALUES OF子句
create table new_demo as select * from demo where 1=0;
select * from new_demo;
select * from demo;

delete new_demo;

DECLARE
  TYPE id_table_type is table of demo.id%TYPE;
  TYPE name_table_type is table of demo.name%TYPE;
  id_table id_table_type;
  name_table name_table_type;
  TYPE index_pointer_type is table of PLS_INTEGER;
  index_pointer index_pointer_type;
BEGIN
  select * bulk collect into id_table,name_table from demo;
  index_pointer:=index_pointer_type(4,6,7);      --将第4,6,7这三行数据复制到new_demo表中
  forall i in values of index_pointer
    insert into new_demo values(id_table(i),name_table(i));
END;

--使用SQL%BULK_ROWCOUNT属性
--属性SQL%BULK_ROWCOUNT是专门为FORALL语句提供的,用于取得在执行批量绑定操作时第i个元素所作用的行数
DECLARE
   TYPE dno_table_type is table of number(3);
   dno_table dno_table_type:=dno_table_type(10,2);
BEGIN
   forall i in 1..dno_table.count
      update emp set sal=sal*1.1 where deptno=dno_table(i);
   dbms_output.put_line('第2个元素更新的行数:'||sql%bulk_rowcount(2));
END;

select * from emp;

--BULK COLLECT子句
--在SELECT INTO语句中使用BULK COLLECT子句
DECLARE
   TYPE emp_table_type is table of emp%ROWTYPE
      INDEX BY BINARY_INTEGER;
   emp_table emp_table_type;
BEGIN
   SELECT * BULK COLLECT INTO emp_table from emp where deptno=&no;
   for i in 1..emp_table.count loop
      dbms_output.put_line('雇员姓名:'||emp_table(i).ename);
   end loop;
END;

--在DML的返回子句中使用BULK COLLECT子句
DECLARE
   TYPE ename_table_type is table of emp.ename%TYPE;
   ename_table ename_table_type;
BEGIN
   DELETE FROM emp where deptno=&no returning ename bulk collect into ename_table;
   dbms_output.put('雇员名:');
   for i in 1..ename_table.count loop
      dbms_output.put(ename_table(i)||' ');
   end loop;
   DBMS_OUTPUT.new_line;
END;

 

分享到:
评论

相关推荐

    精通Oracle.10g.PLSQL编程

    编写控制结构 7.1 条件分支语句 7.2 CASE语句 7.3 循环语句 7.4 顺序控制语句 7.5 习题 第8章 使用复合数据类型 8.1 PL/SQL记录 8.1.1 定义PL/SQL记录 8.1.2 使用PL/SQL...

    Oracle 11g SQL和PL SQL从入门到精通 pdf格式电子书 下载(二)

     第14章 使用复合数据类型  第15章 使用游标  第16章 异常处理 . 第17章 本地动态sql  第18章 pl/sql过程  第19章 pl/sql函数  第20章 pl/sql包  第21章 触发器  第22章 使用对象类型 第四部分 pl/sql系统...

    Oracle 11g SQL和PL SQL从入门到精通 pdf格式电子书 下载(一)

     第14章 使用复合数据类型  第15章 使用游标  第16章 异常处理 . 第17章 本地动态sql  第18章 pl/sql过程  第19章 pl/sql函数  第20章 pl/sql包  第21章 触发器  第22章 使用对象类型 第四部分 pl/sql系统...

    Oracle 11g SQL和PL SQL从入门到精通〖送源代码〗

    本书是专门为Oracle应用开发人员提供的SQL和PL/SQL编程指南。通过学习本书,读者不仅可以掌握Oracle常用工具Oracle Universal Installer、Net Comfiguration Assistant、SQL Developer、SQL*Plus的作用及使用方法,...

    Oracle 11g SQL和PL SQL从入门到精通.part1

     第14章 使用复合数据类型  第15章 使用游标  第16章 异常处理 . 第17章 本地动态sql  第18章 pl/sql过程  第19章 pl/sql函数  第20章 pl/sql包  第21章 触发器  第22章 使用对象类型 第四部分 pl/sql系统...

    Oracle 11g SQL和PL SQL从入门到精通part2 pdf格式电子书 下载(二)

     第14章 使用复合数据类型  第15章 使用游标  第16章 异常处理 . 第17章 本地动态sql  第18章 pl/sql过程  第19章 pl/sql函数  第20章 pl/sql包  第21章 触发器  第22章 使用对象类型 第四部分 pl/sql系统...

    精通Oracle.10g.Pl.SQL编程

    本书包括:PL/SQL 综述、PL/SQL 开发工具、PL/SQL 基础、使用SQL语句、SQL函数、访问Oracle 、编写控制结构、使用复合数据类型、使用游标、处理例外、开发子程序等内容。 作者:王海亮 出版社:中国水利水电出版社

    精通sql结构化查询语句

    1.5 SQL开发环境 1.5.1 SQL环境介绍 1.5.2 SQL的层次结构 1.5.3 SQL环境中的对象 1.5.4 SQL环境中的程序系统 1.6 SQL语句基础 1.6.1 SQL常量 1.6.2 SQL表达式 1.6.3 SQL数据类型 1.6.4 注释符 1.6.5 批处理 1.6.6 ...

    Perl 实例精解(第三版).pdf

    5.2 混合数据类型 5.3 优先权与结合性 5.3.1 赋值运算符 5.3.2 关系运算符 5.3.3 等值运算符 5.3.4 逻辑运算符(短路运算符) 5.3.5 逻辑字运算符 5.3.6 算术运算符 5.3.7 自动递增和自动递减...

    asp.net知识库

    Oracle编程的编码规范及命名规则 Oracle数据库字典介绍 0RACLE的字段类型 事务 CMT DEMO(容器管理事务演示) 事务隔离性的一些基础知识 在组件之间实现事务和异步提交事务(NET2.0) 其它 在.NET访问MySql数据库时的...

Global site tag (gtag.js) - Google Analytics