pl/sql 编程语法
declare --声明变量
var_sal number(5);
var_ename varchar(32);
var_counter number(5) :=0; --变量赋初值,必须这么写
begin
select sal,ename into var_sal,var_ename from emp where empno=7839;--对变量赋值,查询结果只能是一行
var_counter := var_counter+1;
dbms_output.put_line(var_sal);--打印结果
dbms_output.put_line(var_ename);
dbms_output.put_line(var_counter);
end;
--%type 定义数据类型
declare
var_sal emp.sal%type; --var_sal与mp表中al的数据类型一致
var_ename varchar(32);
var_counter number(5) :=0; --变量赋初值,必须这么写
begin
select sal,ename into var_sal,var_ename from emp where empno=7839;--对变量赋值,查询结果只能是一行
var_counter := var_counter+1;
dbms_output.put_line(var_sal);--打印结果
dbms_output.put_line(var_ename);
dbms_output.put_line(var_counter);
end;
---复合类型变量
declare
var_emp emp%rowtype; --复合类型变量
begin
select * into var_emp from emp where empno=7839;--对变量赋值,查询结果只能是一行
--dbms_output.put_line(var_sal);--打印结果
dbms_output.put_line(var_emp.sal);
dbms_output.put_line(var_emp.empno);
end;
declare
type record_type is record ---定义record_type 的结构体
(
v_ename emp.ename%type,
v_sal emp.sal%type,
v_depno emp.deptno%type
);
v_myrecord record_type;---使用ecord_type 定义变量;_myrecord 是一个ecord 变量
begin
select ename ,sal, deptno into v_myrecord from emp where empno = 7839;
dbms_output.put_line(v_myrecord.v_ename);
dbms_output.put_line(v_myrecord.v_depno);
dbms_output.put_line(v_myrecord.v_depno);
end;
-----条件控制if then end if
declare
v_sal emp.sal%type;
begin
select sal into v_sal from emp where ename='SMITHA';
if v_sal<1000 then
dbms_output.put_line('工资'||v_sal);
end if;
exception
when no_data_found then
dbms_output.put_line('未查询导数据||sqlcode||'----'||sqlerrm);
end;
-----条件控制if then else end if
declare
v_sal emp.sal%type;
begin
select sal into v_sal from emp where ename='SMITH';
if v_sal<800 then
dbms_output.put_line('工资'||v_sal);
else
dbms_output.put_line('工资太低);
end if;
exception
when no_data_found then
dbms_output.put_line('未查询导数据||sqlcode||'----'||sqlerrm);
end;
-----条件控制if then elseif .... end if
declare
v_sal emp.sal%type;
begin
select sal into v_sal from emp where ename='SMITH';
if v_sal<2000 then
dbms_output.put_line('工资'||v_sal);
elsif v_sal<800 then
dbms_output.put_line('工资太低);
else
dbms_output.put_line('工资太惨了);
end if;
exception
when no_data_found then
dbms_output.put_line('未查询导数据||sqlcode||'----'||sqlerrm);
end;
-----条件控制case when then else end
case 条件
when 条件结果表达式 then
语句
when 条件结果表达式 then
语句
else
语句
end case;
-----循环控制loop
declare
v_i number(10):=0;
begin
loop -- 开始循环
v_i:=v_i+1;
dbms_output.put_line('v_i当前值为:||v_i);
exit when v_i=10; --循环结束条件
end loop;
end;
-----循环控制for loop
declare
-- v_i number(10):=0;
begin
<<xh>> ---定义循环标签
for v_i in 1..10 loop
dbms_output.put_line('v_i当前值为:||v_i);
end loop xh;
end;
-----循环控制while loop
declare
v_i number(10):=0;
begin
<<xh>> ---定义循环标签
while v_i<10 loop --循环结束条件hile v_i>=10结束循环
dbms_output.put_line('v_i当前值为:||v_i);
v_i:=v_i+1;
end loop xh;
end;
-----循环控制for loop goto 类似于reak
declare
-- v_i number(10):=0;
begin
--<<xh>> ---定义循环标签
for v_i in 1..10 loop
dbms_output.put_line('v_i当前值为:||v_i);
if v_i=5 then
goto xh;
end if;
end loop;
<<xh>> --定义标签输出循环结束
dbms_output.put_line('循环结束);
end;
---游标的使用
----1.显示游标,需要声明,包括打开游标,关闭游标,从游标提取数据,多用于处理elect语句返回多行数据的情形
----2.隐示游标,由系统自动处理,用于配合elect语句查询返回单行数据的处理。
---隐示游标:
--1.SQL%ISOPEN ,判断游标是有打开,总是alse
--2.SQL%FOUND , 判断QL语句是否执行成功,成功为RUE,失败为ALSE.
--3.SQL%NOTFUND ,与相反
--4.SQL%ROWCOUNT , sql执行成功则返回值,不成功则会出现异常
--2.SQL%FOUND
declare
v_empno emp.empno%type:=&empno; --&empno 是参数,手工赋值对变量赋值要加:
begin
update emp set sal= sal+200 where empno = v_empno;
if sql%found then ---判断pdate 是否执行成功
dbms_output.put_line('跟新成功);
else
dbms_output.put_line('跟新失败);
end if;
end;
--4.SQL%ROWCOUNT
declare
v_ename emp.ename%type;
begin
select ename into v_ename from emp where empno=&empno;---不是变量赋值不用加:
if sql%rowcount=0 then ---判断受影响行数
dbms_output.put_line('记录不存在);
else
dbms_output.put_line('the name is '||v_ename||'--'||sql%rowcount);
end if;
exception
when no_data_found then
dbms_output.put_line('记录不存在);
end;
---显示游标
--定义游标ursor cursor_name(para1,....) is select ....
--打开游标pen cursor_name
--读取游标etch cursor_name into var
--关闭游标lose cursor_name
---属性
--cursor_name%rowcount
--cursor_name%found
--cursor_name%notfount
--cursor_name%isopen
declare
cursor cur_emp is select * from emp; --定义游标
v_record emp%rowtype;
begin
open cur_emp; --开启游标
loop --开启循环
fetch cur_emp into v_record; --从游标获取数据
exit when cur_emp%notfound; --当没有记录时退出循环
dbms_output.put_line(v_record.empno||v_record.ename||v_record.sal);
end loop; --循环结束
close cur_emp; --关闭游标
end;
declare
v_empno emp.empno%type;
v_ename emp.ename%type;
v_sal emp.sal%type;
cursor cur_emp is select empno,ename,sal from emp;
begin
open cur_emp;
loop
fetch cur_emp into v_empno,v_ename,v_sal;
exit when cur_emp%notfound;
dbms_output.put_line(v_empno||v_ename||v_sal);
end loop;
close cur_emp;
end;
---游标带参数
declare
v_empno emp.empno%type;
v_ename emp.ename%type;
v_sal emp.sal%type;
cursor cur_emp(p_empno number) is select empno,ename,sal from emp where empno=p_empno;
begin
open cur_emp(7788);
loop fetch cur_emp into v_empno,v_ename,v_sal;
exit when cur_emp%notfound;
dbms_output.put_line(v_empno||v_ename||v_sal);
end loop;
close cur_emp;
end;
----使用for循环来使用游标
declare
cursor emp_cursor is select * from emp;
begin
for temp in emp_cursor loop
dbms_output.put_line(temp.empno||temp.ename||temp.sal);
end loop;
end;
declare
begin
for temp in (select * from emp) loop
dbms_output.put_line(temp.empno||temp.ename||temp.sal);
end loop;
end;
---存储过程
----不带参数
create or replace procedure maxsal
is
v_sal emp.sal%type;
begin
select max(sal) into v_sal from emp;
dbms_output.put_line(v_sal);
end;
create or replace procedure p_emp2
is
cursor cc is select * from emp;
begin
for empx in cc loop
dbms_output.put_line(empx.ename);
end loop;
end;
---调用存储过程
1.call maxsal();
2.
declare
begin
maxsal();
end;
3.使用sqlplus
---带in 参数,in参数再内部不可更改
create or replace procedure p_dept(pdno in number,pdname in varchar2,loc in varchar2)
is
begin
insert into dept (deptno,dname,loc) values (pdno,pdname,loc);
commit;
end;
--调用p_dept
declare
begin
p_dept(50,'aa','bb');
end;
--带out 参数
create or replace procedure p_dept(pdno in number,pdname out varchar2,loc out varchar2)
is
begin
for temp in (select * from dept where deptno=pdno) loop
dbms_output.put_line(temp.dname||temp.loc);
end loop;
end;
--调用p_dept
declare
v_depno dept.deptno%type;
v_dname dept.dname%type;
v_loc dept.loc%type;
begin
p_dept(v_depno,v_dname,v_loc);
end;
---带in out 参数
create or replace procedure swap(a in out number,b in out number)
is
temp number;
begin
temp :=a;
a :=b;
b :=temp;
end;
--调用wap
declare
a number :=1;
b number :=2;
begin
dbms_output.put_line('交换前='||a||'----'||'交换前='||b);
swap(a,b);
dbms_output.put_line('交换后='||a||'----'||'交换后='||b);
end;
----函数
create or replace function 函数名(参数名输入输出类型参数数据类型)
is| as
--声明部分
begin
---程序块
end;
----计算员工工资排名
create or replace function getOrder(pno in number)
return number ---返回值
is
v_sal emp.sal%type;
v_count number(2);
begin
select sal into v_sal from emp where empno = pno;
select count(1) into v_count from emp where sal>v_sal;
v_count :=v_count+1;
return v_count;
exception when no_data_found then
dbms_output.put_line('no data found');
return -1;
end;
select getOrder(7398) from dual;