PL/SQL 二

来源:互联网 发布:读故事的软件下载 编辑:程序博客网 时间:2024/05/17 04:09

四。异常

异常俺就不扯多了,了解一下的异常知识就可以了。

异常分为自定义异常和预定义(系统定义)异常。

自定义异常知道如何声明异常,如何抛出异常,如何捕获异常就行了。。

eg:

     定义异常-- 异常名 exception

     抛出异常--rsise 异常名

     捕获异常--when then 。。。

五游标

游标的概念无论在PLSQL还是TSSQL中都有,是一种方便我们获取数据,操作数据的方式。直接上例子:

/*cursor info*/
declare
  cursor v_cursor is select empno,ename from emp;/*定义游标*/
begin
  if v_cursor%isopen then/*游标是否打开*/

     dbms_output.put_line('v_cursor is open');
   else
     dbms_output.put_line('v_cursor is not open');
      
   end if;
 
    
  open v_cursor;
  if v_cursor%isopen then
     dbms_output.put_line('v_cursor is open');
   end if;
   if v_cursor%notfound then/*游标还有没有下一个元素*/
      dbms_output.put_line('v_cursor is not found');
  
   end if; 
   if v_cursor%found then /*游标是否有下一个元素*/
      dbms_output.put_line('v_cursor is found');
   end if;
 
   dbms_output.put_line(v_cursor%rowcount);

end;


/*cursor loop*/
declare
        cursor cursor_emp is select * from emp;
        v_emp_row emp%rowtype;
begin
        /*while 循环 游标的打开和关闭需要我们手动操作*/
        open cursor_emp;
        fetch cursor_emp into v_emp_row;
        while cursor_emp%found
        loop
              dbms_output.put_line(cursor_emp%rowcount||' '||v_emp_row.empno||' '||v_emp_row.ename);
              fetch cursor_emp into v_emp_row;
        end loop;
        close cursor_emp;
       
        /*for 循环我们不需要关系游标打开和关闭*/
        for v_emp_row in cursor_emp
        loop
            dbms_output.put_line(cursor_emp%rowcount||' '||v_emp_row.empno||' '||v_emp_row.ename);
       
        end loop;
       

end;       

如果我们需要通过游标进行DML操作,我们只需要在定义游标的语句后面加上FOR UPDATE

 

这是个小知识点,我一直用SQLSERVER ,TSSQL中的动态执行SQL的方法很好用。我们在SQLSERVER中不光可以动态执行sql,而且可以定义游标(拼接字符串),动态执行完成后,还能调用该游标,确实太好用了!今天发现Oracle中也有动态执行SQL的方式,只是知道的太少,还需要多学习。。


/*执行动态SQL*/
create or replace procedure execSqlDys
As
       v_FirstName varchar2(10);
       v_Id number(10);
       v_sqlStr varchar2(100);
Begin
       v_FirstName :='execSql3';
       v_Id :=3;
       v_sqlStr := 'update students set Id ='||v_Id||',First_Name = '''||v_FirstName||'''';
       dbms_output.put_line(v_sqlStr);
      
       execute Immediate v_sqlStr;
       commit;
       Exception when others then
                 rollback;


End;

 

七 PLSQL的STATEMENT(子程序)

该部分是重点啦。。

我们知道PLSQL是由STATEMENT组成的,为什么要定义这样的一个概念?我想看完下面的东西,大家应该和我一样,会突然发现PLSQL我们还是小白。。

一。存储过程、函数

这两个东西就不用说了,打架都知道,直接看语法。

格式:
 Create [or  replace] [procedure|function] name(
  //参数
  v_name [in|out| in out默认为in] var_type,--变量类型
 )
 【RETURN  VAR_TYPE--函数时需要返回值,定义返回值的返回类型】

 【AS|IS】
  //变量申明或者类型定义

 BEGIN
  //业务处理  
 Exception
  //异常出来
 END;

 

说明一下几点:

IN,OUT指定参数是传进来还是需要传出去的

参数的传递分为值传递、引用传递。
 IN 默认的为引用传递。
 OUT 默认为值传递。故如果发生异常后,调用存储过程的地方的值不会发生改变。

NOCOPY选项:p_ParameterA OUT NOCOPY NUMBER,使用该选项,参数变为引用传递。如果在执行过程中,发生了异常,因为引用传递,修改了内存中的值,故调用存储过程的地方,该值已经发生了变化。

参数的默认值:
  p_ParameterA NUMBER DEFAULT 10,可以通过DEFAULT关键字(或者:=)设置参数的默认值,这样用户调用该存储过程的时候可以不传入该参数值。

调用存储过程参数的传入方式:
  1.位置对应法;不解释了。
  2.名称对应法:name-mapping:p_ParameterC => v_Variable3, p_ParameterC为对应的存储过程中参数的名称, v_Variable3为要传入的变量。
  3.混合:上面的两种凡是混用,但第一个参数必须是位置对应法。

 

容易出错的参数:

1.如果我们指定char、varchar2实际的长度、或者number的精度等信息会编译出错,这是为什么呢?这就扯到上面说的值传递和应用传递的概念了(如果不知道请看看C/C++或java或C#。。。。任何基本教程),因为这些形参是以引用的方式使用形参,该参数的具体字段信息在调用时从形参中拿到。以上针对IN
 2.如果参数的个数为0,则不需要圆括号

 

 

AS|IS:用AS替代了declare。该关键字的不光具有了declare的功能,也用来对前面的Crate等DDL语句通知commit,即Create procedure ...等进行了COMMIT操作