1 将默认的serveroutput打开 set serveroutput on;
-- 注释一行
/* ... */ 注释多行
2 输出一条HelloWorld语句:
begin
dbms_output.put_line('HelloWorld!');
end;
/
即可看到在屏幕上输出了HelloWorld!(boolean类型不能在屏幕上打印)
3 declare(变量声明)
规则:
1 变量名不能使用保留字,如from、select等(oracle保留字挺多)
2 第一个字符必须是字母(一般约定以 v_ 开头)
3 最多包含30个字符
4 不要与数据库的表或者列同名
5 一行只能声明一个变量
类型:
binary_integer: 整数,主要用来计数而不是用来表示字段类型
number : 数字类型
char : 定长字符串
varchar2 : 变长字符串
date : 日期
long : 长字符串,最长2GB
boolean : 布尔类型,可为true,false,null值,默认null,所以应该初始化
eg:
declare
v_name varchar2(20);
begin
v_name := 'myname'; // := 是赋值语句,与pascal语言相同
dbms_output.put_line(v_name);
end;
/
即可看到在屏幕上输出了myname
-- 注释一行
/* ... */ 注释多行
2 输出一条HelloWorld语句:
begin
dbms_output.put_line('HelloWorld!');
end;
/
即可看到在屏幕上输出了HelloWorld!(boolean类型不能在屏幕上打印)
3 declare(变量声明)
规则:
1 变量名不能使用保留字,如from、select等(oracle保留字挺多)
2 第一个字符必须是字母(一般约定以 v_ 开头)
3 最多包含30个字符
4 不要与数据库的表或者列同名
5 一行只能声明一个变量
类型:
binary_integer: 整数,主要用来计数而不是用来表示字段类型
number : 数字类型
char : 定长字符串
varchar2 : 变长字符串
date : 日期
long : 长字符串,最长2GB
boolean : 布尔类型,可为true,false,null值,默认null,所以应该初始化
eg:
declare
v_name varchar2(20);
begin
v_name := 'myname'; // := 是赋值语句,与pascal语言相同
dbms_output.put_line(v_name);
end;
/
即可看到在屏幕上输出了myname
使用%type属性(可以将程序绑定在某张表的某个字段的类型):
eg: v_empno emp.empno%type;(v_empno的类型和emp表的empno字段的类型相同,这样当表的
类型改变时,可以不必要变得程序了)
使用%rowtype属性(可以将程序绑定在某张表的某一记录)
eg: v_empno emp.empno%type;(v_empno的类型和emp表的empno字段的类型相同,这样当表的
类型改变时,可以不必要变得程序了)
使用%rowtype属性(可以将程序绑定在某张表的某一记录)
复合类型:
Table变量类型(数组)
eg:
declare
type type_table_emp_empno(类型名) is table(是一表) of emp.empno% type index by binary_integer(下标类型);//声明为Table类型
v_empnos type_table_emp_empno; //用上面声明的类型声明变量
begin
v_empnos(0) := 2322;
v_empnos(1) := 2344;
v_empnos(-1) := 2388;//允许下标为负
dbms_output.put_line(v_empnos(-1));
end;
/
Table变量类型(数组)
eg:
declare
type type_table_emp_empno(类型名) is table(是一表) of emp.empno% type index by binary_integer(下标类型);//声明为Table类型
v_empnos type_table_emp_empno; //用上面声明的类型声明变量
begin
v_empnos(0) := 2322;
v_empnos(1) := 2344;
v_empnos(-1) := 2388;//允许下标为负
dbms_output.put_line(v_empnos(-1));
end;
/
4 exception(too_many_rows\no_data_found等)
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;
/
会看到屏幕输出error!即捕获到异常
5 sql语句的运用
select语句:
eg:
declare
v_ename emp.ename%type;
v_sal emp.sal%type;
begin
select ename,sal inot v_ename,v_sal from emp where empno = 10;(必须有 且只有一条记录)
dbms_output.put_line(v_ename || ' ' || v_sal);
end;
/
declare
v_emp emp%rowtype;
begin
select * into v_emp from emp where empno = 10;
dbms_output.put_line(v_emp.ename);
end;
/
insert语句(insert,update,delete语句与sql差不多,看下面例子):
declare
v_deptno dept.deptno%type := 50;
v_dname dept.dname%type := 'aaaa';
v_loc dept.loc%type := 'sh';
begin
insert into dept values (v_deptno, v_name, v_loc);
commit;
end;
/
select语句:
eg:
declare
v_ename emp.ename%type;
v_sal emp.sal%type;
begin
select ename,sal inot v_ename,v_sal from emp where empno = 10;(必须有 且只有一条记录)
dbms_output.put_line(v_ename || ' ' || v_sal);
end;
/
declare
v_emp emp%rowtype;
begin
select * into v_emp from emp where empno = 10;
dbms_output.put_line(v_emp.ename);
end;
/
insert语句(insert,update,delete语句与sql差不多,看下面例子):
declare
v_deptno dept.deptno%type := 50;
v_dname dept.dname%type := 'aaaa';
v_loc dept.loc%type := 'sh';
begin
insert into dept values (v_deptno, v_name, v_loc);
commit;
end;
/
DDL语句:
eg:
begin
execute immediate 'create table T(nnn varchar2(20) default ''aaa'')';
end ;
/
eg:
begin
execute immediate 'create table T(nnn varchar2(20) default ''aaa'')';
end ;
/
控制语句:
eg(like if):
declare
v_sal emp.sal%type;
begin
select sal into v_sal from emp where empno = 10;
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;
/
eg(like do...while):
declare
i binary_integer := 1;
begin
loop
dbms_output.put_line(i);
i := i + 1;
exit when (i >= 11);
end loop;
end;
/
eg(like while):
declare
i binary_integer := 1;
begin
while j < 11 loop
dbms_output.put_line(i);
i := i + 1;
end loop;
end;
/
eg(for):
begin
for k in 1..10 loop
dbms_output.put_line(k);
end loop;
eg(like if):
declare
v_sal emp.sal%type;
begin
select sal into v_sal from emp where empno = 10;
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;
/
eg(like do...while):
declare
i binary_integer := 1;
begin
loop
dbms_output.put_line(i);
i := i + 1;
exit when (i >= 11);
end loop;
end;
/
eg(like while):
declare
i binary_integer := 1;
begin
while j < 11 loop
dbms_output.put_line(i);
i := i + 1;
end loop;
end;
/
eg(for):
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;
/
dbms_output.put_line(k);
end loop;
end;
/
6 cursor(isopen,notfound,found,rowcount四个属性)
eg:
declare
cursor c is
select * from emp;(让游标指向这张表的第一条记录,尚未打开,没加载 内存)
v_emp c%rowtype;(v_emp存储游标中的一条记录)
begin
open c;
fetch c into v_emp;(拿到一条记录放入v_emp中,游标自动下移一格)
exit when (c%notfound);
dbms_output.put_line(v_emp.ename);//打印ename的所有的属性值,顺序不能颠倒
close c;(用完游标后,释放内存)
end;
/
eg:
declare
cursor c is
select * from emp;
v_emp c%rowtype;
begin
open c;
fetch c into v_emp;
while (c%found) loop;
dbms_output.put_line(v_emp.ename);
fetch c into v_emp;
end loop;
close c;
end;
/
eg:
declare
cursor c is
select * from emp;
v_emp c%rowtype;
begin
for v_emp in c loop;(自动打开、关闭、fetch,所以不易出错,常用)
dbms_output.put_line(v_emp.ename);
end loop;
end;
/
eg:
declare
cursor c is
select * from emp;(让游标指向这张表的第一条记录,尚未打开,没加载 内存)
v_emp c%rowtype;(v_emp存储游标中的一条记录)
begin
open c;
fetch c into v_emp;(拿到一条记录放入v_emp中,游标自动下移一格)
exit when (c%notfound);
dbms_output.put_line(v_emp.ename);//打印ename的所有的属性值,顺序不能颠倒
close c;(用完游标后,释放内存)
end;
/
eg:
declare
cursor c is
select * from emp;
v_emp c%rowtype;
begin
open c;
fetch c into v_emp;
while (c%found) loop;
dbms_output.put_line(v_emp.ename);
fetch c into v_emp;
end loop;
close c;
end;
/
eg:
declare
cursor c is
select * from emp;
v_emp c%rowtype;
begin
for v_emp in c loop;(自动打开、关闭、fetch,所以不易出错,常用)
dbms_output.put_line(v_emp.ename);
end loop;
end;
/
eg:
declare
cursor c(v_deptno emp.deptno%type, v_jop emp.job%type)(函数游标)
is
select ename,sal from emp where deptno = v_deptno and job = v_job;
--v_temp c%rowtype;//不需要声明
begin
for v_temp in c(30,'clerk') loop
dbms_output.put_line(v_temp.ename);
end loop;
end;
/
eg(可更新的游标):
delcare
crosor c
is
select * from emp2 for update;
--v_temp c%rowtype;
begin
for v_temp in c loop;
if(v_temp.sal < 2000) then
update emp2 set sal = sal * 2 where current of c;//更新当前 游标指向的记录
elsif (v_tmp.sal = 5000) then
delete from emp2 where current of c;
end if;
end loop;
commit;
end;
/
7 存储过程(带名字的pl_sql语言)
create or replace procedure p
is
corsor c is
select * from emp2 for update;
begin
for v_temp in c loop;
if(v_temp.sal < 2000) then
update emp2 set sal = sal * 2 where current of c;//更新当前游标指向的记录
elsif (v_tmp.sal = 5000) then
delete from emp2 where current of c;
end if;
end loop;
commit;
end;
执行时用 exec p; 或
delcare
crosor c
is
select * from emp2 for update;
--v_temp c%rowtype;
begin
for v_temp in c loop;
if(v_temp.sal < 2000) then
update emp2 set sal = sal * 2 where current of c;//更新当前 游标指向的记录
elsif (v_tmp.sal = 5000) then
delete from emp2 where current of c;
end if;
end loop;
commit;
end;
/
7 存储过程(带名字的pl_sql语言)
create or replace procedure p
is
corsor c is
select * from emp2 for update;
begin
for v_temp in c loop;
if(v_temp.sal < 2000) then
update emp2 set sal = sal * 2 where current of c;//更新当前游标指向的记录
elsif (v_tmp.sal = 5000) then
delete from emp2 where current of c;
end if;
end loop;
commit;
end;
执行时用 exec p; 或
begin
p;
end;
带参数的存储过程:
eg:
create or replace procedure p
(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;
/
使用:
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_a);
dbms_output.put_line(v_ret);
dbms_output.put_line(v_temp);
end;
/
如果出现警告,编译错误时,可用 show error来查看错误源(即使有语法错误,过程仍然会被创建)
p;
end;
带参数的存储过程:
eg:
create or replace procedure p
(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;
/
使用:
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_a);
dbms_output.put_line(v_ret);
dbms_output.put_line(v_temp);
end;
/
如果出现警告,编译错误时,可用 show error来查看错误源(即使有语法错误,过程仍然会被创建)
8 函数:
create or replace function sal_tax //创建一个函数,一个数值参数和一个数值返回值
(v_sal number)
return 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;//定义的函数和‘系统’函数调用方法相同
9 触发器:
eg:
//创建表
cretae table emp2_log
(
uname varchar2(20),
action varchar2(10),
actime date
);
//触发器
create or replace trigger trig
after insert or delete or update on emp2 (for each row(每有一个操作就触发一次))
begin
if inserting then
insert into emp2_log values(user,'insert',sysdate);
eslif updating then
insert into emp2_log values(user,'update',sysdate);
esl if deleting then
insert into emp2_log values(user,'delete',sysdate);
end if;
end;
/
此时查看emp2_log表时就可看到对emp2执行操作的记录
eg:
//创建表
cretae table emp2_log
(
uname varchar2(20),
action varchar2(10),
actime date
);
//触发器
create or replace trigger trig
after insert or delete or update on emp2 (for each row(每有一个操作就触发一次))
begin
if inserting then
insert into emp2_log values(user,'insert',sysdate);
eslif updating then
insert into emp2_log values(user,'update',sysdate);
esl if deleting then
insert into emp2_log values(user,'delete',sysdate);
end if;
end;
/
此时查看emp2_log表时就可看到对emp2执行操作的记录
触发器的副作用:
当dept表中的deptno被其他表参考时,如果要更新deptno的值,可强制用触发器实现:
create or replace trigger trig
after update on dept
for each row
begin
update emp set deptno = :NEW.deptno where deptno = :OLD.deptno;
end;
/
此时更新deptno不会报违反完整性约束的错了:
update dept set deptno = 77 where deptno = 10; 可看到已更新一行的提示
转载于:https://blog.51cto.com/yqsshr/103680