马士兵存储过程sql

这可是我一个字符一个字符的敲上去的,希望对诸位有用。
--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);

你可能感兴趣的:(sql)