原文地址:http://blog.sina.com.cn/s/blog_885b4ace0100y8kp.html
38_PL_SQL_1.avi
PL/SQL 是在Oracle里面的一种编程语言,是一种新的编程语言,在Oracle内部使用的编程语言。
每一种数据库都有这样的一种语言
一种语言最重要的是:数据类型,语法。
PL语言(procedure language 面向过程的语言)是为了补充SQL语言的,是带有了分支和循环的语言
PL语言很简单,分四块,
第一块:declare(可选)声明各种变量,游标。
第二块:begin 程序从这开始执行
第三块:exception
第四块:end
第一个简单的程序:
begin
dbms_output.put_line('HelloWorld');
end;
/
必须先执行 set serveroutput on; 命令(因为serveroutput(内部环境变量)默认为off),再执行上面的程序就能打印出结果
39_PL_SQL_2.avi
第二个小例子:
declare
v_name varchar2(20);
begin
v_name := 'myname';
dbms_output.put_line(v_name);
end;
/
再来认识一下整个语句块的构成:
declare
v_num number := 0; //PLSQL中约定变量名以V_开头
begin
v_num := 2/v_num; // := 代表赋值
dbms_output.put_line(v_num);
exception
when others then //其他的情况固定格式必须这样写
dbms_output.put_line('error');
end;
/
40_PL_SQL_3.avi 简单的变量
----------变量声明规则----------
变量名不能使用保留字,如from,select等
第一个字符必须是字母
变量名最多包含30个字符
不要与数据库的表或者列同名
每一行这能声明一个变量
----------变量的声明----------
binary_integer:整数,主要用来计数而不是用来表示字段类型 比number效率高
number:数字类型
char:定长字符串
varchar2:变长字符串
date:日期
long:长字符串,最长2GB
boolean:布尔类型,可以取值true,false,null//最好给一初值,默认为null值
在PL/SQL里面boolean类型变量在定义的时候一定要给初始值
一个数据类型的例子:
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;
v_valid boolean := false;
v_name varchar2(20) not null := 'MyName';
begin
dbms_output.put_line('v_temp value:' || v_temp); // ||是字符串连接符
end;
/
Oracle 里面的put_line()不能打印boolean类型的值
dbms_output.put_line('v_temp value:' || v_valid); //报错
oracle中的变量主要用来存储表中某些字段的值,如v_sal来存储 emp表中的 sal
*查看当前用户:show user
----------变量的声明,使用 '%type'属性---------
declare
v_empno number(4);
v_empno2 emp.empno%type;//表示类型和emp这张表的empno字段类型相同,当empno类型改动时,不需要再到 这里改动v_empno2,会自动变换
v_empno3 v_empno2%type; //%type属性,可以用于变量身上
begin
dbms_output.put_line('Test');
end;
/
//使用%type属性,可以使变量的声明根据表字段的类型自动变换,省去了维护的麻烦,而且% type属性,可以用于变量身上
PL/SQL 里面--表示注释掉一行,/* */注释多行
41_PL_SQL_4.avi
复杂的变量:
复合变量有两种:
第一种:table 相当于java里面的数组Array[]
在PL/SQL里面要声明数组,也要指定它的类型,PL/SQL里比较复杂,
必须重新定义新的类型,这里先声明类型,再用类型声明变量,下标允许有负值
例子:
declare
type type_table_emp_empno is table of emp.empno%type index by binary_integer;
v_empnos type_table type_table_empno;
begin
v_empnos(0) := 7345;
v_empnos(-1) :=9999;
dbms_output.put_line(v_empnos(-1));
end;
/
第二种:record 相当于java里面的类
42_PL_SQL_3.avi
Record变量类型 相当于java里面的类
例子:
declare
type type_record_dept is record
(
deptno dept.deptno%type,
dname dept.dname%type,
loc dept.loc%type
);
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;
/
--record的缺陷:当dept这张表结构变化时,增加或删除一个字段时,type里面也需要改动。因此可以使用 %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;
/
43_PL_SQL_5.avi
PL/SQL里面--SQL语句的运用
用select语句,必须返回一条记录,并且只能返回一条记录。//如果返回太多,我变量装不了
PL/SQL里面的select语句如果不用游标的话,必须和into语句一块用并且有且只有一条记录,没有不行,多了也不行。select语句必须能后返回一条记录。
例子1:
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;
/
例子2:select语句的应用(record)
declare
v_emp emp%rowtype;
begin
select * into v_emp from emp where empno = 7369;
dbms_output.put_line(v_emp.ename);
end;
/
其他语句的运用:
例子3:
declare
v_deptno dept.deptno%type := 50;
v_dname dept.dname%type := 'aaaa';
v_loc dept.loc%type := 'bj';
begin
insert into dept2 values (v_deptno, v_dname, v_loc);
commit;
end;
例子4:
declare
v_deptno emp2.deptno%type := 10;
v_count number;
begin
--update emp2 set sal = sal/2 where deptno = v_deptno;
--select deptno into v_deptno from emp2 where empno = 7369;
select count(*) into v_count from emp2;
dbms_output.put_line (sql%rowcount || '条记录被影响');
commit;
end;
注:sql%rowcount 统计上一条sql语句更新的记录条数
44_PL_SQL_6.avi
PL/SQL 里面的DDL语句,需要加execute immediate
例子1:
begin
execute immediate 'create table T (nnn varchar2(20) default ''aaa'')';
end;
if语句:
取出7369的薪水,如果<1200, 则输出'low',如果 <2000 则输出 'middle', 否则'high'
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;
45_PL_SQL_7.avi
--循环 1
declare
i binary_integer := 1;
begin
loop
dbms_output.put_line(i);
i := i+1;
exit when ( i>=11);
end loop;
end;
上面的循环相当于java里的 do-while 循环
--循环 2
declare
j binary_integer := 1;
begin
while j < 11 loop
dbms_output.put_line(j);、
j := j + 1;
end loop;
end;
以上循环相当于 java 里的 while 循环
--循环 3
begin
for k in 1..10 loop
dbms_output.put_line(k);
end loop;
for k in reverse 1..10 loop //reverse表示逆序
dbms_output.put_line(k);
end loop;
end;
以上循环相当于 java 里的 增强 for 循环
46_PL_SQL_8.avi
--错误处理
例子1:
declare
v_temp number(4);
begin
select empno into v_temp from emp where deptno = 10; --这条记录会返回很多值,所以产生异常
exception
when too_many_rows then
dbms_output.put_line('太多记录了');
when others then
dbms_output.put_line('error');
end;
没有找着数据的异常:
例子:
declare
v_temp number(4);
begin
select empno into v_temp from emp where empno = 2222;
exception
when no_data_found then
dbms_output.put_line('没数据');
end;
DBA经常使用的一种用来记录错误的做法:
例子:
创建表
create table errorlog
(
id number primary key,
errcode number,
errmsg varchar2(1024),
errdate date
);
创建序列sequence
create sequence seq_errorlog_id start with 1 increment by 1;
写你的程序
declare
v_deptno dept.deptno%type := 10;
v_errcode number;
v_errmsg varchar2(1024);
begin
delete from dept where deptno = v_deptno;
commit;
exception
when others then
rollback;
v_errcode := SQLCODE;//SQLCODE是关键字,代表出错的代码
v_errmsg := SQLERRM;//SQLERRM是关键字,代表出错的信息
insert into errorlog values (seq_errorlog_id.nextval, v_errcode, v_errmsg, sysdate);
commit;
end;
执行
select * from errorlog;
报错误;
delete from dept where detpno = 10;
报错误
查看具体的出错时间:
select to_char (errdate, 'YYYY-MM-DD HH24:MI:SS') from errorlog;
书:P44--P45页