这可是我一个字符一个字符的敲上去的,希望对诸位有用。 --PL/QL---------- --------------------------------------------------------------- set serveroutput on;--开启输出方法 begin dbms_output.put_line('HelloWorld!'); end; / ------------------------------------------------------------ --声明赋值 declare v_name varchar2(20); begin v_name := 'myname'; dbms_output.put_line(v_name); end; / ----------------------------------------------------------------- --展示错误 declare v_num number := 0; begin v_num := 2/v_num; dbms_output.put_line(v_num); end; / ---------------------------------------------------------------- --捕捉错误 declare v_num number := 0; begin v_num := 2/v_num; dbms_output.put_line(v_num); exception when others then dbms_output.put_line('error'); end; / ------------------------------------------------------------------- --变量声明的规则 1. 变量名不能够使用保留字,如from,select等 2. 第一个字符必须是字母 3. 变量名最多包含30个字符 4. 不要与数据库的表或者列同名 5. 每一行只能声明一个变量 --常用变量类型 1. binary_integer:整数,主要用来计数而不是用来表示字段类型 2. number:数字类型 3. char:定长字符串 4. varchar2:变长字符串 5. date:日期 6. long:长字符串,最长2GB 6. boolean:布尔类型,可以取值为true,false和null值 ------------------------------------------------------------------------ --declare变量的声明 declare v_temp number(1); v_count binary_integer :=0; v_sal number(7,2) := 4000.00; v_date date := sysdate; v_pi constant number(3,2) := 3.14;--constant表示常量 v_valid boolean := false;--不能打印Boolean类型变量的值 v_name varchar2(20) not null := 'MyName'; begin dbms_output.put_line('v_temp value:' || v_count); end; / --------------------------------------------------------------------------- --创建emp表 create table emp ( empno number(4) not null , ename varchar(10), job varchar(9), hiredate date, sal number(7,2), deptno number(4), primary key(empno) ); commit; insert into emp values(7369,'smith','computer','',1300,10); insert into emp values(110,'jerry','computer','',1300,10); insert into emp values(119,'lucy','computer','',1300,50); ------------------------------------------------------------------------------- --变量声明,使用%type属性 declare v_empno number(4); v_empno2 emp.empno%type;--声明变量v_empno2为emp表中empno字段的类型 v_empno3 v_empno2%type;--声明变量v_empno3为变量v_empno2的类型 begin dbms_output.put_line('Test'); end; / ------------------------------------------------------------------------------- --复合类型变量(table,Record) --table变量类型(相当于数组) declare --自定义类型type_table_emp_empno为emp表empno字段类型,下标用整数表示 type type_table_emp_empno is table of emp.empno%type index by binary_integer; v_empnos type_table_emp_empno;--用自定的类型声明变量 begin v_empnos(0) := 7369; v_empnos(2) := 7839; v_empnos(-1) := 9999; dbms_output.put_line(v_empnos(-1)); end; / --------------------------------------------------------------------------------------- --创建dept表 create table dept ( deptno number(4) not null , dname varchar(10), loc varchar(100), primary key(deptno) ); ---------------------------------------------------------------------------------- --Record变量类型(相当java中的类) declare type type_record_dept is record--自定义类型type_record为record类型 ( deptno dept.deptno%type,--deptno为dept表depno字段类型 dname dept.dname%type,--dname为dept表dname字段类型 loc dept.loc%type--loc为dept表loc字段的类型 ); v_temp type_record_dept;--用自定义变量 begin v_temp.deptno := 50; v_temp.dname := 'aaaa'; v_temp.loc := 'bj'; dbms_output.put_line(v_temp.deptno || ' ' || v_temp.dname); end; / ---------------------------------------------------------------------------------- --使用%rowtype声明record变量 declare v_temp dept%rowtype; begin v_temp.deptno := 50; v_temp.dname := 'aaaa'; v_temp.loc := 'bj'; dbms_output.put_line(v_temp.deptno || ' ' || v_temp.dname); end; / --------------------------------------------------------------------------- --SQL语句的运用 declare v_ename emp.ename%type; v_sal emp.sal%type; begin select ename,sal into v_ename,v_sal from emp where empno = 7369; dbms_output.put_line(v_ename ||' '|| v_sal); end; / ---------------------------------------------------------------------- --未找到记录错误 declare v_ename emp.ename%type; v_sal emp.sal%type; begin select ename,sal into v_ename,v_sal from emp where empno = 111; dbms_output.put_line(v_ename ||' '|| v_sal); end; / --------------------------------------------------------------------- --返回多条记录错误 declare v_ename emp.ename%type; v_sal emp.sal%type; begin select ename,sal into v_ename,v_sal from emp where dept = 10; dbms_output.put_line(v_ename ||' '|| v_sal); end; / ------------------------------------------------------------------------- ----保证有且仅有一条记录 declare v_emp emp%rowtype; begin select * into v_emp from emp where empno = 7369; dbms_output.put_line(v_emp.ename); end; / ------------------------------------------------------------------------- declare v_deptno dept.deptno%type := 50; v_dname dept.dname%type := 'aaaa'; v_loc dept.loc%type := 'bj'; begin insert into dept values (v_deptno,v_dname,v_loc); commit; end; / --------------------------------------------------------------------------- declare v_deptno emp.deptno%type := 50; v_count number; begin update emp set sal = sal/2 where deptno = v_deptno; select deptno into v_deptno from emp where empno=110; select count(*) into v_count from emp;--最后产生几个值就有几条记录被影响。 dbms_output.put_line(sql%rowcount ||'条记录被影响'); commit; end; / ---------------------------------------------------------------------------- begin execute immediate 'create table T (nnn varchar2(20) default ''aaa'')'; end; / ---------------------------------------------------------------------------- declare v_sal emp.sal%type; begin select sal into v_sal from emp where empno=7369; if(v_sal< 1200) then dbms_output.put_line('low'); elsif(v_sal <2000) then dbms_output.put_line('middle'); else dbms_output.put_line('high'); end if; end; / ------------------------------------------------------------------- --循环 declare i binary_integer := 1; begin loop dbms_output.put_line(i); i:=i+1; exit when (i>=11); end loop; end; / ---------------------------------------------------------------------- declare i binary_integer := 1; begin while i<11 loop dbms_output.put_line(i); i:=i+1; end loop; end; / --------------------------------------------------------------------------- begin for k in 1..10 loop dbms_output.put_line(K); end loop; for k in reverse 1..10 loop--倒序 dbms_output.put_line(K); end loop; end; / ------------------------------------------------------------------------------ --错误处理 declare v_temp number(4); begin select empno into v_temp from emp where deptno=10; exception when too_many_rows then--出现too_many_rows错误 dbms_output.put_line('太多记录了'); when others then--出现别的错误 dbms_output.put_line('error'); end; / ------------------------------------------------------------------------------------- --创建一个记录错误的表 create table errorlog ( id number primary key, errcode number, errmsg varchar2(1024), errdate date ); create sequence seq_errorlog_id start with 1 increment by 1;--递增序列 ---------------------------------------------------------------------------------------- declare v_temp number(4); --v_deptno emp.deptno%type := 20; v_errcode number; v_errmsg varchar2(1024); begin select empno into v_temp from emp where deptno=10; --delete from emp where deptno = v_deptno; --commit; exception when others then rollback;--回滚 v_errcode := SQLCODE;--错误的代码 v_errmsg:=SQLERRM;--错误的原因 insert into errorlog values(seq_errorlog_id.nextval,v_errcode,v_errmsg,sysdate); commit; end; ---------------------------------------------------------------------------------------------- --游标 declare cursor c is--定义一个游标c指向结果集 select * from emp; v_emp emp%rowtype;--定义一个record类型的变量v_emp begin open c;--打开游标指向第一条记录 fetch c into v_emp;--将游标指向记录的字段值放到v_emp变量中 dbms_output.put_line(v_emp.ename); close c;--关闭游标 end; / ------------------------------------------------------------------------------------- declare cursor c is--定义一个游标c指向结果集 select * from emp; v_emp emp%rowtype;--定义一个record类型的变量v_emp begin open c;--打开游标指向第一条记录 loop --将游标指向记录的字段值放到v_emp变量中,每fetch一次游标循下移一条记录 fetch c into v_emp; exit when (c%notfound);--游标移出结果集,则退出 dbms_output.put_line(v_emp.ename); end loop; close c; end; / ------------------------------------------------------------------------------------- declare cursor c is--定义一个游标c指向结果集 select * from emp; v_emp emp%rowtype;--定义一个record类型的变量v_emp begin open c;--打开游标指向第一条记录 fetch c into v_emp;--将游标指向记录的字段值放到v_emp变量中,游标并循下移一条记录 while(c%found) loop fetch c into v_emp;--游标下移一条记录 dbms_output.put_line(v_emp.ename);--当游标指向空时,会打印上最近一条记录的值 end loop; close c; end; / ------------------------------------------------------------------------------------------ declare cursor c is--定义一个游标c指向结果集 select * from emp; v_emp emp%rowtype;--定义一个record类型的变量v_emp begin open c;--打开游标指向第一条记录 fetch c into v_emp;--将游标指向记录的字段值放到v_emp变量中,游标循环下移 while(c%found) loop dbms_output.put_line(v_emp.ename); fetch c into v_emp; end loop; close c; end; / ---------------------------------------------------------------------------------- --for循环游标,最常用 declare cursor c is select * from emp; begin for v_emp in c loop--游标循环下移,并将当前记录字段值存入record变量v_emp中 dbms_output.put_line(v_emp.ename); end loop; end; / ---------------------------------------------------------------------------------- --带参数的游标 declare cursor c(v_deptno emp.deptno%type,v_job emp.job%type) is select ename,sal from emp where deptno=v_deptno and job=v_job; begin for v_temp in c(10,'computer') loop dbms_output.put_line(v_temp.ename); end loop; end; / ---------------------------------------------------------------------------------------- --可更新的游标 declare cursor c is select * from emp for update; begin for v_temp in c loop if(v_temp.sal<2000) then update emp set sal=sal*2 where current of c; elsif (v_temp.sal=5000) then delete from emp where current of c; end if; end loop; commit; end; / --------------------------------------------------------------------------------- 存储过程(pl/sql块) create or replace procedure p--创建或替换一个存储过程P,没有则创建,有则替换 is cursor c is select * from emp for update; begin for v_temp in c loop if(v_temp.deptno=10) then update emp set sal=sal+10 where current of c; elsif (v_temp.sal=20) then update emp set sal=sal+20 where current of c; else update emp set sal=sal+50 where current of c; end if; end loop; commit; end; / --执行存储过程------- 方法一:exec p; --------------------------------------------------------------------------------------- 方法二: begin p; end; / --带参数存储执过程------- create or replace procedure p --in:传入参数,out为传出参数,默认为in (v_a in number,v_b number,v_ret out number, v_temp in out number) is begin if(v_a>v_b) then v_ret:=v_a; else v_ret:=v_b; end if; v_temp:=v_temp+1; end; / --------------------------------------------------------------------------------- show error--显示pl/sql错误 ------------------------ --调用存储过程-- declare v_a number:=3; v_b number:=4; v_ret number; v_temp number:=5; begin p(v_a,v_b,v_ret,v_temp); dbms_output.put_line(v_ret); dbms_output.put_line(v_temp); end; / -------------------------------------------------------------------------- --自定义函数-- create or replace function sal_tax (v_sal number)--参数是number类型 return number--返回一个number类型的值 is begin if(v_sal<2000) then return 0.10; elsif(v_sal<2750) then return 0.15; else return 0.20; end if; end; / select lower(ename),sal_tax(sal) from emp;--测试函数 ------------------------------------------------------------------------------- --触发器trigger-- --创建一个记录表 create table emp_log ( uname varchar2(20),--谁 action varchar2(10),--做了什么操作 atime date--什么时间 ); ---------------------------------------------------------------------------------- create or replace trigger trig --当在emp表中完成插入,删除,更新后(before)触发trig触发器 after insert or delete or update on emp--多行操作只产生一条记录 begin if inserting then insert into emp_log values(user,'insert',sysdate); elsif updating then insert into emp_log values(user,'update',sysdate); elsif deleting then insert into emp_log values(user,'delete',sysdate); end if; end; / update emp set sal=sal*2 where deptno=10; ------------------------------------------------------------------------------------------- create or replace trigger trig --当在emp表中完成插入,删除,更新后(before)触发trig触发器 after insert or delete or update on emp for each row--几行操作只产生几条记录 begin if inserting then insert into emp_log values(user,'insert',sysdate); elsif updating then insert into emp_log values(user,'update',sysdate); elsif deleting then insert into emp_log values(user,'delete',sysdate); end if; end; / update emp set sal=sal*2 where deptno=10; -------------------------------------------------------------------------------------------- drop trigger trig;--删除触发器 ------------------------------------------------------------------------------------------------- create or replace trigger trig after update on dept for each row begin update dept set deptno=:NEW.deptno where deptno=:OLD.deptno;--新状态更换旧状态 end; / update dept set deptno=99 where deptno=50;--违反完整性约束条件 ----------------------------------------------------------------------------------------------------- create table article ( id number primary key,--帖子编号 cont varchar2(4000),--帖子内容 pid number,--父id isleaf number(1),--0代表非叶子节点,1代表叶子节点 alevel number(2)--处于第几层 ); insert into article values (1,'蚂蚁大战大象',0,0,0); insert into article values (2,'大象被打趴下了',1,0,1); insert into article values (3,'蚂蚁也不好过',2,1,2); insert into article values (4,'瞎说',2,0,2); insert into article values (5,'没有瞎说',4,1,3); insert into article values (6,'怎么可能',1,0,1); insert into article values (7,'怎么没有可能',6,1,2); insert into article values (8,'可能性是很大的',6,1,2); insert into article values (9,'大象近医院了',2,0,2); insert into article values (10,'护士是蚂蚁',9,1,3); ------------------------------------------------------------------------------------------------------- ****蚂蚁大战大象 ********大象被打趴下了 ************蚂蚁也不好过 ************瞎说 ****************没有瞎说 ************大象近医院了 ****************护士是蚂蚁 ********怎么可能 ************怎么没有可能 ************可能性是很大的 -------------------------------------------------------------------------------------------------- create or replace procedure p(v_pid article.pid%type) is cursor c is select * from article where pid=v_pid; begin for v_article in c loop dbms_output.put_line(v_article.cont); if(v_article.isleaf=0) then p(v_article.id); end if; end loop; end; / exec p(0); ---------------------------------------------------------------------------------------------------- create or replace procedure p(v_pid article.pid%type,v_level binary_integer) is cursor c is select * from article where pid=v_pid; v_preStr varchar2(1024):=''; begin for i in 0..v_level loop v_preStr:=v_preStr||'****'; end loop; for v_article in c loop dbms_output.put_line(v_preStr||v_article.cont); if(v_article.isleaf=0) then p(v_article.id,v_level+1); end if; end loop; end; / exec p(0,0);