Oracle PL/SQL


plsql的一般结构体:

declare(可选,声明各种变量和游标的地方)
begin(必要的,从此开始执行)
exception(抓取到异常后执行的)
end;

[sql] view plaincopy

  1. set serveroutput on;(默认是关闭)  

  2. ---简简单单的plsql输出

  3. begin  

  4.   dbms_output.put_line('HelloWorld!');  

  5. end;  

  6. ---定义一本字符串变量,并输出,oracle中的:=是赋值,= 是运算符(类似>,<)

  7. declare  

  8.    v_name varchar2(20);  

  9. begin  

  10.   v_name := 'myname';  

  11.   dbms_output.put_line(v_name);  

  12. end;  

  13. ---

  14. declare  

  15.   v_num number := 0;  

  16. begin  

  17.   v_name := 2/v_num;  

  18.   dbms_output.put_line(v_name);  

  19.   exception  

  20.     when others then  

  21.       dbms_output.put_line('error');  

  22. end;  

--变量声明

  注:每一行只能声明一个变量

--常用变量类型

1.  binary_integer: 整数,主要用来计数而不是用来表示字段类型,效率高
2.  number: 数字类型
3.  char: 定长字符串
4.  varchar2: 变长字符串
5.  date: 日期
6.  long: 长字符串,最长2GB
7.  boolean: 布尔类型,可以取值为ture、false和null值,一定要给初值,

--变量声明

[sql]  

  1. declare  

  2.   v_temp number(1);  

  3.   v_count binary_integer := 0;  

  4.   v_sal number(7,2) := 4000.00;  

  5.   v_date date := sysdate;  

  6.   v_pi constant number(3,2) := 3.14;  

  7.   v_valid boolean := false;  

  8.   v_name varchar2(20) not null := 'MyName';  

  9. begin  

  10.   dbms_output.put_line('v_temp value:' || v_count);  

  11. end;  

--变量声明,使用%type属性

[sql]  

  1. /*注释多行*/ --注释一行  

  2. declare  

  3.   v_empno number(4);  

  4.   v_empno2 emp.empno%type;--用表内字段类型声明变量类型  

  5.   v_empno3 v_empno2%type;--用变量type属性声明变量类型  

  6. begin  

  7.   dbms_output.put_line('Test');  

  8. end;  

--简单变量赋值

[sql]  

  1. declare  

  2.   v_name varchar2(20);  

  3.   v_sal number(7,2);  

  4.   v_sal2 number(7,2);  

  5.   v_valid boolean := false;  

  6.   v_date date;  

  7. begin  

  8.   v_name := 'MyName';  

  9.   v_sal := 23.77;  

  10.   v_sal2 := 23.77;  

  11.   v_valid := (v_sal = v_sal2);--判断是否相等用=  

  12.   v_date := to_date('1999-08-12 12:23:30','YYYY-MM-DD HH24:MI:SS');  

  13. end;  

--Table变量类型,表示一个数组

[sql]  

  1. declare  

  2.   type type_table_emp_empno is table of emp.empno%type index by binary_integer;--首先声明一个类型  

  3.   v_empnos type_table_emp_empno;--再用这个类型声明变量  

  4. begin  

  5.   v_empnos(0) := 7369;  

  6.   v_empnos(2) := 7839;  

  7.   v_empnos(-1) := 9999;  

  8.   dbms_output.put_line(v_empnos(-1));---1访问不到,0,2可以访问到  

  9. end;  

--Record类型,表示一个类

[sql] 

  1. declare  

  2.    type type_record_dept is record  

  3.    (  

  4.     deptno dept.deptno%type,  

  5.     dname dept.dname%tpye,  

  6.     loc dept.loc%type  

  7.   );  

  8.   v_temp type_record_dept;  

  9. begin  

  10.   v_temp.deptno := 50;  

  11.   v_temp.dname := 'aaaa';  

  12.   v_temp.loc := 'bj';  

  13.   dbms_output.put_line(v_temp.deptno || ' ' || v_temp.dname);  

  14. end

 

--使用%rowtype声明record变量

[sql]  

  1. declare  

  2.   v_temp dept%rowtype;  

  3. begin  

  4.   v_temp.deptno := 50;  

  5.   v_temp.dname := 'aaaa';  

  6.   v_temp.loc := 'bj';  

  7.   dbms_output.put_line(v_temp.deptno || ' ' || v_temp.dname);  

  8. end;  


--PL/SQL里执行select语句的话,配合into(单个变量赋值),必须返回并只能返回一条记录

[sql]  

  1. declare  

  2.   v_ename emp.ename%type;  

  3.   v_sal emp.sal%type;  

  4. begin  

  5.   select ename,sal into v_ename,v_sal from emp where empno = 7369;  

  6.   dbms_output.put_line(ename || ' ' || v_sal);  

  7. end;  

  8.   

  9. declare  

  10.   v_emp emp%rowtype;  

  11. begin  

  12.  select * into v_emp from emp where empno = 7369;  

  13.  dbms_output.put_line(v_emp.ename);  

  14. end;  

  15.   

  16. declare  

  17.   v_deptno dept.deptno%type := 50;  

  18.   v_dname dept.dname%type := 'aaaa';  

  19.   v_loc dept.loc%type := 'bj';  

  20. begin  

  21.   insert into dept2 values(v_deptno,v_dname,v_loc);  

  22.   commit;--别忘了!!!  

  23. end;  

  24.   

  25. select * from dept2;  

  26.   

  27. declare  

  28.   v_deptno emp2.deptno%type := 10;  

  29.   v_count number;  

  30. begin  

  31.   --update emp2 set sal = sal/2 where deptno = v_deptno;  

  32.   --select deptno into v_deptno from emp2 where empno = 7369;  

  33.   select count(*) into v_count from emp2;  

  34.   dbms_output.put_line(sql%rowcount || '条记录被影响');//sql,关键字,代表刚刚执行的sql程序  

  35. end



--PL/SQL执行DDL语句,需要加execute immediate

[sql]  

  1. begin  

  2.   execute immediate 'create table T(nnn varchar2(20) default ''aaaa'')';  

  3. end

     

--if语句

[sql]  

  1. --取出7369的薪水,如果<1200,则输出'low',如果<2000则输出'middle',否则输出'high'  

  2.   

  3. declare  

  4.   v_sal emp.sal%type;  

  5. begin  

  6.   select sal into v_sal from emp where empno = 7369;  

  7.   if (v_sal<1200) then  

  8.     dbms_output.put_line('low');  

  9.   elsif(v_sal<2000) then --elsif没e  

  10.     dbms_output.put_line('midddle');  

  11.   else  

  12.     dbms_output.put_line('high');  

  13.   end if;  

  14. end;  


--循环

[sql] 

  1. declare  

  2.   i binary_integer := 1;  

  3. begin  

  4.   loop  

  5.     dbms_output.put_line(i);  

  6.     i := i + 1;  

  7.     exit when (i >= 11);  

  8.  end loop;  

  9. end;  

  10.   

  11. declare  

  12.  j binary_integer := 1;  

  13. begin  

  14.   while j < 11 loop  

  15.     dbms_output.put_line(j);  

  16.     j := j + 1;  

  17.   end loop;  

  18. end;  

  19.   

  20. begin  

  21.   for k in 1..10 loop  

  22.     dbms_output.put_line(k);  

  23.   end loop;  

  24.    

  25.   for k in reverse 1..10 loop  

  26.     dbms_output.put_line(k);  

  27.   end loop;  

  28. end;  


--错误处理

[sql]  

  1. declare  

  2.   v_temp number(4);  

  3. begin  

  4.   select empno into v_temp from emp where deptno = 10;  

  5. exception  

  6.   when too_many_rows then  

  7.     dbms_output.putline('太多记录了');  

  8.   when others then  

  9.     dbms_output.put_line('error');  

  10. end;  

  11.   

  12. declare  

  13.   v_temp number(4);  

  14. begin  

  15.   select empno into v_temp from emp where empno = 2222;  

  16. exception  

  17.   when no_data_found then  

  18.     dbms_output.put_line('没有数据');  

  19. end;  


--sql程序跨数据库平台较好,PL/SQL效率高

--DBA,错误日志

[sql]  

  1. create table errorlog  

  2. (  

  3.   id number primary key,  

  4.   errcode number,  

  5.   errmsg varchar2(1024),  

  6.   errdate date  

  7. );  

  8.   

  9. create sequence seq_errorlog_id start with 1 increment by 1;  

  10.   

  11. declare  

  12.   v_deptno dept.deptno%type := 10;  

  13.   v_errcode number;  

  14.   v_errmsg varchar2(1024);  

  15. begin  

  16.   delete from dept where deptno = v_deptno;  

  17.   commit;  

  18. exception  

  19.   when others then  

  20.     rollback;  

  21.     v_errcode := SQLCODE;  

  22.     v_errmsg := SQLERRM;  

  23.     insert into errorlog values (seq_errorlog_id.nextval,v_errcode,v_errmsg,sysdate);  

  24.     commit;  

  25. end;  

  26. 游标,触发器见下文