----储过程编译错误

--案例05:存储过程编译错误解决
create or replace procedure testproc
as
begin
select * from emp;
end;

  --解决办法01:
  show errors
    /*数据库会自动提示编译错误的原因!*/
  --解决方法02:
select * from user_errors;

 

 

--案例06:带有参数的存储过程完整案例
  --新建代码过程
create or replace procedure runbyparameters
(isal in emp.sal%type, --输入指定的工资
sname out varchar, /*输出查询的结果:姓名*/
--sjob in out emp.job%type --输入工作,输出‘找到’或‘没有找到’
sjob in out varchar
/*如果作为输出时类型最好使用长一些的字符型号可以保证
能够保存输出结果;所以输出参数通常不需要带精度,输入参数可以带精度!*/
)
as
icount number;/*过程内部变量声明,用于记录查询到符合条件的记录数目*/
begin
  select count(*) into icount from emp
  where sal>isal and job=sjob;/*根据两个输入参数将结果给输出参数*/
  if icount=1 then
  select ename into sname from emp where sal>isal and job=sjob;
/*查找到的信息情况*/
   sname:=' 姓名为 :'||sname||'的职工 工资:'||to_char(isal);
   sjob:='工作为:'||sjob;
else
   sname:='没有查到工资为:'||to_char(isal);
    sjob:=' 工作为:'||sjob||' 的记录!';
end if;
exception
   when too_many_rows then
      dbms_output.put_line('返回的值多余一行!');
   when others then
     dbms_output.put_line ('执行过程中发生了不可预知的错误!');
end;

 --调用该存储过程
declare
 realsal emp.sal%type;
 realname varchar(40);
 realjob varchar(40); --emp.job%type;
begin
  realsal:=1100;
  realname:='';
  realjob:='CLERK';
/*第一次调用*/
runbyparameters(realsal, realname, realjob);
dbms_output.put_line(realname||'  '||realjob);
/*第二次调用*/
realjob:='MANAGER';
runbyparameters(2900, realname, realjob);
dbms_output.put_line(realname||'  '||realjob);
/*第三次调用*/
runbyparameters
(isal=>realsal, sname=>realname, sjob=>realjob);
dbms_output.put_line('带有联合符号'||realname||''||realjob);
end;

--如果分步骤执行则如下:
--第一次调用:
declare
 realsal emp.sal%type;
 realname varchar(40);
 realjob varchar(40); --emp.job%type;
begin
  realsal:=1100;
  realname:='';
  realjob:='CLERK';
/*第一次调用*/
runbyparameters(realsal, realname, realjob);
dbms_output.put_line(realname||'  '||realjob);
end;


--第二次调用:
declare
 realsal emp.sal%type;
 realname varchar(40);
 realjob varchar(40); --emp.job%type;
begin
  realsal:=1100;  --由于调用时使用了2900则这里的1100实效
  realname:='';
  realjob:='CLERK';
/*第二次调用*/
realjob:='MANAGER';
runbyparameters(2900, realname, realjob);
dbms_output.put_line(realname||'  '||realjob);
end;

--第三次调用:

declare
 realsal emp.sal%type;
 realname varchar(40);
 realjob varchar(40); --emp.job%type;
begin
  realsal:=1100;
  realname:='';
  realjob:='CLERK';
/*第三次调用*/
runbyparameters
(isal=>realsal, sname=>realname, sjob=>realjob);
dbms_output.put_line('带有联合符号'||realname||''||realjob);
end;


 

-------自主事务

--案例07:需要使用自主事务的情况
/*步骤1:新建过程p1*/
create or replace procedure p1
as
begin
  insert into student values (106, '成龙', '男');
  rollback;
end;

/*步骤2:新建内部调用过程P1的过程P2*/
create or replace procedure p2
as
begin
  update student set sex='女';
  p1;  --调用过程P1
end;

/*
由于P2过程调用时会调用过程P1,P2过程先更新值,再运行P1的插入值并且回滚,这里的rollback
只是影响插入的操作还是把更新和插入的操作都回滚呢?

*/

/*步骤3:调用过程P2验证结果:*/
execute p2;
select * from student;

 

--案例08:使用自主事务

/*步骤1:编译新建过程P1*/
create or replace procedure p1
as
  pragma autonomous_transaction;
begin
  insert into student values (106, '成龙', '男');
  rollback;
end;

/*验证结果*/
--运行过程P2
execute p2;
select * from student;