pl/sql表+记录习题2+动态游标

1.使用表类型,结构如下:
  varchar2(10);
使用for循环插入1到10(除了6和8)的数据到表变量中
declare
  TYPE r_table_type IS TABLE OF resu.resu%TYPE
       INDEX BY BINARY_INTEGER;
       --------
       r_tab r_table_type;
begin
  FOR i IN 1..10 LOOP
  IF i <> 6 AND i <> 8 THEN
  INSERT INTO resu
  VALUES(i);
  END IF;
r_tab(i)=i;
-------------
 
  END LOOP;
 
end;

2.检索emp表中所有数据(编号,姓名,部门,工资)
将数据存储到表变量中,并将其工资〉8000的员工打印出来
-- Created on 2012-3-20 by NEW
declare
  TYPE e_table_type IS TABLE OF emp%ROWTYPE
       INDEX BY BINARY_INTEGER;
       e_tab e_table_type;
BEGIN
     SELECT *
    BULK collect INTO e_tab
     FROM emp;
  FOR i IN e_tab.FIRST..e_tab.LAST LOOP
  IF e_tab(i).sal >500 THEN
  dbms_output.put_line(e_tab(i).empno
                            ||','
                            || e_tab(i).empno
                            || ','
                            ||e_tab(i).deptno
                            || ','
                            ||e_tab(i).sal);
  END IF;
  END LOOP;
 
end;
3.汇总每个部门每个职位员工的最高及平均工资,包括显示部门名称
和职位名称,将数据存储到Test表中。要求使用表变量
DECLARE
  
       
        TYPE table_type IS TABLE OF test%Rowtype
        INDEX BY BINARY_INTEGER;
       
        tablename table_type;
     
        TYPE type_name IS RECORD
        (MAXX NUMBER,    
        AVGG NUMBER,    
        DEPTNOO NUMBER,
        JOBB VARCHAR2(9));
        recordtype type_name;
       
BEGIN
   
   SELECT MAX(sal),AVG(sal),deptno,job
  BULK collect INTO tablename
   FROM emp
   GROUP BY deptno,job;

 FOR i IN tablename.FIRST..tablename.LAST LOOP
   INSERT INTO test
   VALUES(
    tablename(i).maxx,
    tablename(i).avgg,
    tablename(i).deptnoo,
    tablename(i).jobb
    );
      END LOOP;
END;
_____________________________________________________________________________
PL/SQL Developer Test script 3.0
52
declare
  --定义表
  TYPE emp_table IS TABLE OF emp%ROWTYPE
       INDEX BY BINARY_INTEGER;
  r_emp emp_table;   
  --定义职位id
  TYPE emp_jobid IS TABLE OF emp.job%TYPE
       INDEX BY BINARY_INTEGER;
  e_jobid emp_jobid;           -----------职位的表数据   
 
  --定义变量
  ms emp.sal%TYPE;    ---------最大工资
  ass emp.sal%TYPE;   --------------最小工资
  di emp.deptno%TYPE;             ------部门名称
begin
  SELECT distinct(job)
  BULK COLLECT INTO e_jobid--------这问信息存到表数据中
  FROM emp
  ------------选择条件是不同部门之间
  WHERE deptno IN (SELECT DISTINCT(deptno) FROM emp);
 
 
  FOR i IN e_jobid.FIRST..e_jobid.LAST LOOP
      dbms_output.put(e_jobid(i));
       SELECT MAX(sal)
       INTO ms
       FROM emp-------不同部门,不同职位之间的最高工资
       WHERE job=e_jobid(i);
       dbms_output.put(' '||'最高工资是'||ms);
      
       SELECT AVG(sal)
       INTO ass-------不同部门,不同职位之间的平均工资
       FROM emp
       WHERE job=e_jobid(i);
       dbms_output.put(' '||'平均工资是'||asS);
     
     /*   SELECT distinct(deptno)
      INTO di
      FROM emp
       WHERE job=e_jobid(i);
       dbms_output.put_line(' '||'所属部门'||di);*/
      
     SELECT MAX(deptno)
       INTO di
       FROM emp
       WHERE job=e_jobid(i);
       dbms_output.put_line(' '||'所属部门'||di);
  END LOOP;
 
 
--------------有漏洞---必须是job_id完全不一样
end;
_________________________________________________________________________________________
DECLARE
  
       
        TYPE table_type IS TABLE OF test%Rowtype
        INDEX BY BINARY_INTEGER;
       
        tablename table_type;
     
    --    TYPE type_name IS RECORD
     --   (MAXX NUMBER,    
      --  AVGG NUMBER,    
       -- DEPTNOO NUMBER,
       -- JOBB VARCHAR2(9));
      
       -- recordtype type_name;
      
      
       -- TYPE table_type IS TABLE OF type_name
      --  INDEX BY BINARY_INTEGER;
       
      --  tablename table_type;
       
BEGIN
   
   SELECT MAX(sal),AVG(sal),deptno,job
  BULK collect INTO tablename
   FROM emp
   GROUP BY deptno,job;

 FOR i IN tablename.FIRST..tablename.LAST LOOP
   INSERT INTO test
   VALUES(
    tablename(i).maxx,
    tablename(i).avgg,
    tablename(i).deptnoo,
    tablename(i).jobb
    );
      END LOOP;
END;
__________________________________________________________________________________
游标做法
-- Created on 2012-3-22 by NEW
declare
  CURSOR cur_name IS-----这里要添加别名
   SELECT MAX(salary) mm,AVG(salary) aa,department_id,job_id
 -- BULK collect INTO tablename
   FROM employees
   GROUP BY department_id,job_id
   ORDER BY department_id;
  
   re_name cur_name%ROWTYPE;
begin
 -- OPEN cur_name;
  FOR re_name IN cur_name LOOP
  dbms_output.put_line(re_name.department_id|| ','
                       ||re_name.job_id || ','
                       ||re_name.mm|| ','
                       ||re_name.aa);
 
  END LOOP;
 -- CLOSE cur_name;
 
end;
______________________________________________________________________________________
declare
  TYPE m_type IS RECORD(
         depid NUMBER(4),
         depnm varchar2(25),
         jobid varchar2(20),
         jobnm varchar2(35),
         maxsal NUMBER(8,2),
         avgsal NUMBER(8,2)
                        );
  r_sum m_type;
 
  TYPE m_table IS TABLE OF m_type
         INDEX BY BINARY_INTEGER;
        
  t_sum m_table;
begin
  SELECT emp.department_id,
         dep.department_name,
         emp.job_id,
         job.job_title,
         MAX(emp.salary),
         AVG(emp.salary)
  BULK COLLECT INTO t_sum
  FROM   employees emp,
         departments dep,
         jobs job
  WHERE  emp.department_id = dep.department_id
  AND    emp.job_id = job.job_id
  GROUP BY emp.department_id,
           emp.job_id,
           dep.department_name,
           job.job_title
  ORDER BY emp.department_id,
           emp.job_id;
 
  FOR i IN t_sum.FIRST..t_sum.LAST LOOP
      r_sum := t_sum(i);
     
      INSERT INTO test3
      VALUES(r_sum.depid,r_sum.depnm,
             r_sum.jobid,r_sum.jobnm,
             r_sum.maxsal,r_sum.avgsal);
  END LOOP;
 
  COMMIT;
end;
______________________________________________________________________________
利用表和记录就可以不用创建表查询

-- Created on 2012-3-22 by NEW
declare
  TYPE m_type IS RECORD(
         depid NUMBER(4),
         depnm varchar2(25),
         jobid varchar2(20),
         jobnm varchar2(35),
         maxsal NUMBER(8,2),
         avgsal NUMBER(8,2)
                        );
  r_sum m_type;
 
  TYPE m_table IS TABLE OF m_type---m_type是记录
         INDEX BY BINARY_INTEGER;
        
  t_sum m_table;
begin
  SELECT emp.department_id,
         dep.department_name,
         emp.job_id,
         job.job_title,
         MAX(emp.salary),
         AVG(emp.salary)
  BULK COLLECT INTO t_sum
  FROM   employees emp,
         departments dep,
         jobs job
  WHERE  emp.department_id = dep.department_id
  AND    emp.job_id = job.job_id
  GROUP BY emp.department_id,
           emp.job_id,
           dep.department_name,
           job.job_title
  ORDER BY emp.department_id,
           emp.job_id;
 
  dbms_output.put_line(SQL%ROWCOUNT);
 
  FOR i IN t_sum.FIRST..t_sum.LAST LOOP
      r_sum := t_sum(i);--把表记录结果赋给记录
     

      dbms_output.put_line(
              r_sum.depid||r_sum.depnm||
             r_sum.jobid||r_sum.jobnm||
             r_sum.maxsal||r_sum.avgsal);
  END LOOP;
 
  --dbms_output.put_line(SQL%ROWCOUNT);
 
 -- COMMIT;
 
  --dbms_output.put_line(SQL%ROWCOUNT);
end;

总结:

/*记录是存储在多个字段中的一组相关的数据项,每个字段
都有自己的名字和数据类型,把字段的集合当作一个整体的逻辑单元,
主要用于从表中取出查询到的行数据
record中,引入type类型-------------------
例:emp_record.Job:= ‘CLERK‘;
SELECT empno,ename,job
INTO emp_record
FROM emp
WHERE ename= ‘SMITH‘
record可以看作是行的集合
2、声明的变量对应于数据库表或视图中列的集合,
在%ROWTYPE 之前加上数据库表名,
记录内字段的名字和数据类型参照表或视图中的列;
优点:不必知道数据库中列的数量和类型,运行期间列的数量和类型可能
发生改变,在select语句中使用该属性可以有效的检索表中的行

3、table类型,结果类似于其他语言中的数组类型,有两部分组成
--主键:binary_integer
--列:标量和记录类型
table类型没有长度的限制,可以动态增长
可以把其他记录类型,运用到table类型中,所以table更加灵活

TYPE m_type IS RECORD(
         depid NUMBER(4),
         depnm varchar2(25),
         jobid varchar2(20),
         jobnm varchar2(35),
         maxsal NUMBER(8,2),
         avgsal NUMBER(8,2)
                        );
  r_sum m_type;
 
  TYPE m_table IS TABLE OF m_type---m_type是记录
         INDEX BY BINARY_INTEGER;
        
  t_sum m_table;

*/


__________________________________________________________________________________
动态游标
在变量声明部分定义的游标是静态的,不能在程序运行过程中修改。虽然可以通过参数传递来取得不同的数据,但还是有很大的局限性。通过采用动态游标,可以在 程序运行阶段随时生成一个查询语句作为游标。要使用动态游标需要先定义一个游标类型,然后声明一个游标变量,游标对应的查询语句可以在程序的执行过程中动 态地说明。
定义游标类型的语句如下:
TYPE 游标类型名 REF CURSOR;
声明游标变量的语句如下:
游标变量名 游标类型名;
在可执行部分可以如下形式打开一个动态游标:
OPEN 游标变量名 FOR 查询语句字符串;
【训练2】  按名字中包含的字母顺序分组显示雇员信息。
输入并运行以下程序:

Sql代码
declare  
 type cur_type is ref cursor; 
 cur cur_type; 
 rec scott.emp%rowtype; 
 str varchar2(50); 
 letter char:= 'A'; 
begin 
        loop         
         str:= 'select ename from emp where ename like ''%'||letter||'%'''; 
         open cur for str; 
         dbms_output.put_line('包含字母'||letter||'的名字:'); 
          loop 
         fetch cur into rec.ename; 
         exit when cur%notfound; 
        dbms_output.put_line(rec.ename); 
end loop; 
  exit when letter='Z'; 
  letter:=chr(ascii(letter)+1); 
 end loop; 
end; 

运行结果为:

Sql代码
包含字母A的名字: 
ALLEN 
WARD 
MARTIN 
BLAKE 
CLARK 
ADAMS 
JAMES 
包含字母B的名字: 
BLAKE 
包含字母C的名字: 
CLARK 
SCOTT 

说明:使用了二重循环,在外循环体中,动态生成游标的SELECT语句,然后打开。通过语句letter:=chr(ascii(letter)+1)可获得字母表中的下一个字母。

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值