游标练习

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了游标练习相关的知识,希望对你有一定的参考价值。


record类型示例(%type):
set serveroutput on
declare
v_empno emp.empno%type;
type  emp_record is record
(ename  emp.ename%type,
sal     emp.sal%type,
deptno  emp.deptno%type);
v_emp_rec  emp_record;
begin
  select ename,sal,deptno into v_emp_rec from emp where empno=&v_empno;
  dbms_output.put_line(‘Employees name is: ‘||v_emp_rec.ename);
  dbms_output.put_line(‘Employees salary is: ‘||v_emp_rec.sal);
  dbms_output.put_line(‘Employees deptno is: ‘||v_emp_rec.deptno);
end;
/

declare
  type emp_record is record(ename emp.ename%type, sal emp.sal%type, deptno emp.deptno%type);
  v_emp_rec emp_record;
begin
  select ename, sal, deptno into v_emp_rec from emp where empno = #
  dbms_output.put_line(v_emp_rec.ename || ‘ ‘ || v_emp_rec.sal || ‘ ‘ || v_emp_rec.deptno);
end;
/




record类型示例(%rowtype)
declare
  v_emp_rec  emp%rowtype;

begin
  select * into v_emp_rec from emp where empno=#
  dbms_output.put_line(‘Employees name is: ‘||v_emp_rec.ename);
  dbms_output.put_line(‘Employees salary is: ‘||v_emp_rec.sal);
  dbms_output.put_line(‘Employees deptno is: ‘||v_emp_rec.deptno);
  dbms_output.put_line(‘Employees hiredate is: ‘||v_emp_rec.hiredate);
end;
/

record类型示例(%rowtype),如果日期类型不对,可以用to_char函数转换
declare
  v_emp_rec  emp%rowtype;

begin
  select * into v_emp_rec from emp where empno=#
  dbms_output.put_line(‘Employees name is: ‘||v_emp_rec.ename);
  dbms_output.put_line(‘Employees salary is: ‘||v_emp_rec.sal);
  dbms_output.put_line(‘Employees deptno is: ‘||v_emp_rec.deptno);
  dbms_output.put_line(‘Employees hiredate is: ‘||to_char(v_emp_rec.hiredate,‘yyyy-mm-dd‘));
end;
/




table类型示例(只有一列数据需要显示):
SQL> declare
  2    type emp_table is table of emp.ename%type index by binary_integer;
  3    v_emp_table emp_table;
  4  begin
  5    select ename into v_emp_table(1) from emp where empno = 7788;
  6    select ename into v_emp_table(2) from emp where empno = 7369;
  7    select ename into v_emp_table(3) from emp where empno = 7499;
  8    dbms_output.put_line(‘Name is: ‘ || v_emp_table(1));
  9    dbms_output.put_line(‘Name is: ‘ || v_emp_table(2));
 10    dbms_output.put_line(‘Name is: ‘ || v_emp_table(3));
 11  end;
 12  /
Name is: SCOTT
Name is: SMITH
Name is: ALLEN
PL/SQL procedure successfully completed

table类型示例(有多列数据需要显示):
declare
  type emp_tab_ename is table of emp.ename%type index by binary_integer;
  type emp_tab_sal is table of emp.sal%type index by binary_integer;
  v_emp_tab_ename emp_tab_ename;
  v_emp_tab_sal   emp_tab_sal;
begin
  select ename into v_emp_tab_ename(1) from emp where empno = 7788;
  select ename into v_emp_tab_ename(2) from emp where empno = 7369;
  select ename into v_emp_tab_ename(3) from emp where empno = 7499;
  select sal into v_emp_tab_sal(1) from emp where empno = 7788;
  select sal into v_emp_tab_sal(2) from emp where empno = 7369;
  select sal into v_emp_tab_sal(3) from emp where empno = 7499;
  dbms_output.put_line(‘Name is: ‘ || v_emp_tab_ename(1) ||‘ Salary is: ‘ || v_emp_tab_sal(1));
  dbms_output.put_line(‘Name is: ‘ || v_emp_tab_ename(2) ||‘ Salary is: ‘ || v_emp_tab_sal(2));
  dbms_output.put_line(‘Name is: ‘ || v_emp_tab_ename(3) ||‘ Salary is: ‘ || v_emp_tab_sal(3));
end;
/






如果要处理多行多列数据:
在table类型里嵌套record就可以处理多行多列
declare
 type emp_table_type is table of emp%rowtype index by binary_integer;
 v_emp_table_type  emp_table_type;
begin
  select * into v_emp_table_type(1) from emp where empno=7788;
  select * into v_emp_table_type(2) from emp where empno=7369;
  dbms_output.put_line(‘7788 Ename is: ‘||v_emp_table_type(1).ename);
  dbms_output.put_line(‘7788 salary is: ‘||v_emp_table_type(1).sal);
  dbms_output.put_line(‘7788 Department is: ‘||v_emp_table_type(1).deptno);
  dbms_output.put_line(‘7369 Ename is: ‘||v_emp_table_type(2).ename);
  dbms_output.put_line(‘7369 salary is: ‘||v_emp_table_type(2).sal);
  dbms_output.put_line(‘7369 Department is: ‘||v_emp_table_type(2).deptno);
end;
/








DML操作可以同时处理多行

pl/sql里嵌套dml操作(可能影响多行,需注意)
select 默认只能处理单行数据
dml可以处理多行数据
1 插入数据

插入数据示例:
declare
  v_id   t1.id%type;
  v_name t1.name%type;
  v_dsc  t1.dsc%type;
  t1_rcd t1%rowtype;
begin
  v_id   := 10;
  v_name := ‘tom‘;
  v_dsc  := 12;
  insert into t1 values (v_id, v_name, v_dsc);
  commit;
  select * into t1_rcd from t1 where id = v_id;
  dbms_output.put_line(‘T1 record is : ‘ || t1_rcd.id || ‘,‘ ||t1_rcd.name || ‘,‘ || t1_rcd.dsc);
end;
/



插入示例:
begin
  insert into t1 select * from t1;
  commit;
end;
/




更新示例:
declare
  v_name t1.name%type := ‘rose‘;
begin
  update t1 set name = v_name where id = 10;
  commit;
end;
/



删除示例:
declare
  v_id t1.id%type;
begin
  v_id:=10;
  delete from t1 where id=v_id;
  commit;
end;
/



pl/sql中使用事务控制
 DECLARE
   v_deptno dept.deptno%TYPE := 20;
 BEGIN
   DELETE FROM dept WHERE deptno = v_deptno;
   COMMIT;
 EXCEPTION
   WHEN OTHERS THEN
     ROLLBACK;
 end;






cursor游标
oracle在执行sql语句时,为sql语句所分配的一个私有的内存区域
当oracle在执行sql,会建立一个cursor(私有的内存区域)     
默认:建立隐式游标(select,一次只能处理一行数据)
隐式游标特点:
1 oracle自动创建
2 自动open
3 数据处理完成自动close
4 select一次只能处理一行数据

隐式游标用于处理select insert  update  delete语句


显示游标:由开发人员定义,可以通过循环方式处理多行数据(select)
1 开发人员按需定义
2 手工open
3 fetch取值(通过循环读取数据)
4 手工close

显示游标用于处理多行select语句







隐式游标:一次只能返回一行结果(不需要定义,默认)
显示游标:需要用户提前定义,可以通过循环的方式处理游标里的sql语句,返回多行结果

隐式游标的属性:
sql%rowcout 统计在游标中处理的记录数
sql%found   如果在游标中能找到符合条件的一条记录,结果为true
sql%notfound 如果在游标中能找不到符合条件的一条记录,结果为true
sql%open    判断游标是否打开,在隐式游标中默认游标自动打开





隐式游标的几个属性:
truncate table t1;
sql%notfound属性
declare
  v_id t1.id%type;
begin
  v_id:=10;
  update t1 set id=20 where id=v_id;
  if sql%notfound then
  insert into t1(id) values (v_id);
  commit;
  end if;
end;
/


sql%found属性
declare
  v_id t1.id%type;
begin
  v_id:=10;
  delete from t1  where id=v_id;
  if sql%found then
  dbms_output.put_line(‘T1 record is delete!‘);
  commit;
  end if;
end;
/

以上是关于游标练习的主要内容,如果未能解决你的问题,请参考以下文章

游标练习

ps/sql游标练习

2017-07-31(触发器,包,游标练习)

mysql sp 练习游标和预编译

Oracle——触发器和游标练习题

Oracle——触发器和游标练习题