Table of Contents
关键字: goto ,exit,continue,return
2.2 带参数的游标for循环传递参数方式,定义游标使用用default指定默认值
3 非预定义 使用语句关联:pragma exception_init(异常情况,错误代码)
5 在 PL/SQL 中使用 SQLCODE, SQLERRM
1.2 参数的传递,使用位子(v_num)或者名称(emp_count=>v_num,dept_id=>80)表示或者混合
2.2 调用存储过程 :使用 SHOW ERROR 命令来提示源码的错误位置;
七、 execute immediate用法详解(into赋值和using传参)
1 创建的包为 demo_pack, 该包中包含一个记录变量 DeptRec、两个函数和一个过程。
一、PL/SQL
declare
v_statement varchar2(500);
begin
v_statement:='create table zjx_temp( id number)';
execute immediate v_statement;
end;
二、PL/SQL 块结构和组成元素
PL/SQL 程序由三个块组成,即声明部分、执行部分、异常处理部分
set serveroutput on 先要执行这个id
1 、PL/SQL 块的结构如下:
2、PL/SQL 块可以分为三类:
declare
v_sal varchar2(20);
begin
select 20 into v_sal from dual ;
dbms_output.put_line(v_sal);
end;
declare
v_orgcode varchar2(20);
v_name varchar2(255);
begin
select c.user_name,c.inside_org_code into v_name,v_orgcode from cafs_user c where c.id=125;
dbms_output.put_line(v_name);
dbms_output.put_line(v_orgcode);
dbms_output.put_line(v_name||','||v_orgcode);
end;
declare
v_emp_record cafs_user%rowtype;
v_ann_name cafs_announcement.ann_name%type;
begin
select * into v_emp_record from cafs_user where id =125;
dbms_output.put_line(v_emp_record.user_name);
update cafs_announcement a set a.ann_name = 'aaa' where a.id = 77;
select a.ann_name into v_ann_name from cafs_announcement a where a.id = 77;
dbms_output.put_line(v_ann_name);
end;
3、标识符
建议的命名方法:
4、记录类型
declare
v_emp_record cafs_user%rowtype;
begin
select * into v_emp_record from cafs_user where id =125;
dbms_output.put_line(v_emp_record.user_name);
end;
declare
--定义一个记录类型
type user_record is record(
v_orgcode varchar2(20),
v_name cafs_user.user_name%type
);
--定义一个记录类型的成员变量
v_user_record user_record;
begin
select c.inside_org_code,c.user_name into v_user_record from cafs_user c where c.id=125;
dbms_output.put_line(v_user_record.v_name);
dbms_output.put_line(v_user_record.v_orgcode);
dbms_output.put_line(v_user_record.v_name||','||v_user_record.v_orgcode);
end;
declare
type user_record is record(
v_orgcode cafs_user.inside_org_code%type ,
v_name cafs_user.user_name%type
);
v_user_record user_record;
v_temp varchar2(22) :='abc';
begin
select c.inside_org_code,c.user_name into v_user_record from cafs_user c where c.id=125;
dbms_output.put_line(v_user_record.v_name);
dbms_output.put_line(v_user_record.v_orgcode);
dbms_output.put_line(v_user_record.v_name||','||v_user_record.v_orgcode);
dbms_output.put_line(v_temp);
end;
declare
type user_record is record(
v_orgcode cafs_user.inside_org_code%type ,
v_name cafs_user.user_name%type
);
v_user_record user_record;
v_temp varchar2(22) :='abc';
begin
v_temp :='刘德华';
select c.inside_org_code,c.user_name into v_user_record from cafs_user c where c.id=125;
dbms_output.put_line(v_user_record.v_name);
dbms_output.put_line(v_user_record.v_orgcode);
dbms_output.put_line(v_user_record.v_name||','||v_user_record.v_orgcode);
dbms_output.put_line(v_temp);
end;
5、使用%TYPE
declare
v_orgcode varchar2(20);
v_name cafs_user.user_name%type;
begin
select c.user_name,c.inside_org_code into v_name,v_orgcode from cafs_user c where c.id=125;
dbms_output.put_line(v_name);
dbms_output.put_line(v_orgcode);
dbms_output.put_line(v_name||','||v_orgcode);
end;
6、使用%ROWTYPE
PL/SQL 提供%ROWTYPE 操作符, 返回一个记录类型, 其数据类型和数据库表的数据结构相一致。
declare
v_emp_record cafs_user%rowtype;
begin
select * into v_emp_record from cafs_user where id =125;
dbms_output.put_line(v_emp_record.user_name);
end;
7、PL/SQL 表(嵌套表)
8、运算符和表达式(数据定义)
8.1 变量赋值
布尔值只有 TRUE, FALSE 及 NULL 三个值。
三、PL/SQL 流程控制语句
1 条件判断
方式一:if ... then ... elseif ...then ... else ... end if;
方式二:case ... when ...then ..when ... then .... end;
注意:case when 语法有多种,如果then 后面是执行语句要加分号结果,那么结果用end case结束
如果是结果那么不用分号,那么结果是end结束。
if<布尔表达式> then
...
end if;
if<布尔表达式> then
...
else
...
end if;
if<> then
...
elsif <> then
....
else
...
end if;
如果是结果那么不用分号,并且结果是end结束。
1
case 变量|字段
when 比对值 then 执行语句;
when 比对值 then 执行语句;
else 执行语句;
end case;
2
case 变量|字段
when 比对值 then 结果
when 比对值 then 结果
else 结果
end ;
3
case when 表达式 then 执行语句;
when 表达式 then 执行语句;
else 执行语句;
end case;
4
case when 表达式 then 结果
when 表达式 then 结果
else 结果
end ;
declare
v_emp_record cafs_user%rowtype;
v_ann_name cafs_announcement.ann_name%type;
begin
select * into v_emp_record from cafs_user where id =125;
dbms_output.put_line(v_emp_record.user_name);
select a.ann_name into v_ann_name from cafs_announcement a where a.id = 77;
if v_ann_name = 'aaa' then
dbms_output.put_line('aaa');
else
dbms_output.put_line('bbb');
end if;
end;
declare
v_emp_record cafs_user%rowtype;
v_ann_name cafs_announcement.ann_name%type;
begin
select * into v_emp_record from cafs_user where id =125;
dbms_output.put_line(v_emp_record.user_name);
select a.ann_name into v_ann_name from cafs_announcement a where a.id = 77;
if v_ann_name = 'aaa' then dbms_output.put_line('aaa');
elsif v_ann_name ='bbb' then dbms_output.put_line('bbb');
else dbms_output.put_line('ccc');
end if;
end;
declare
v_emp_record cafs_user%rowtype;
v_ann_name cafs_announcement.ann_name%type;
v_ann_number number(4,2);
v_dname varchar2(20) ;
v_deptno number(4,2) :=10;
begin
select * into v_emp_record from cafs_user where id =125;
dbms_output.put_line(v_emp_record.user_name);
select a.ann_name into v_ann_name from cafs_announcement a where a.id = 77;
if v_ann_name = 'aaa' then dbms_output.put_line('aaa');
elsif v_ann_name ='bbb' then dbms_output.put_line('bbb');
else dbms_output.put_line('ccc');
end if;
case v_ann_name
when 'aaa' then dbms_output.put_line('aaa');
when 'bbb' then dbms_output.put_line('bbb');
else dbms_output.put_line('ccc');
end case;
case when v_ann_name = 'aaa' then dbms_output.put_line('aaa');
when v_ann_name = 'bbb' then dbms_output.put_line('bbb');
else dbms_output.put_line('ccc');
end case;
v_ann_number := case v_ann_name when 'aaa' then 0
when 'bbb' then 1
else 2
end;
dbms_output.put_line('v_ann_number='||v_ann_number);
v_dname := case when v_deptno = 10 then '总经办'
when v_deptno = 20 then '综管部'
when v_deptno=30 then '市场部'
else '其他'
end;
dbms_output.put_line(v_dname);
end;
2 循环语句三种方式
方式一:loop... exit when ... end loop;
方式二:while...loop .. end loop;
方式三:for i in ... loop ... end loop;
*****loop exit when end loop事例** v_nu:= v_nu+1; 可以写在exit when前面也可以在下面****
declare
v_nu number(30,2) :=1;
begin
loop
dbms_output.put_line(v_nu);
exit when v_nu >=100;
v_nu:= v_nu+1;
end loop;
end;
declare
v_nu number(30,2) :=1;
begin
loop
dbms_output.put_line(v_nu);
v_nu:= v_nu+1;
exit when v_nu >100;
end loop;
end;
******while loop end loop 循环******
declare
v_nu number(30,2) :=1;
begin
while v_nu <=100 loop
dbms_output.put_line(v_nu);
v_nu := v_nu+1;
end loop;
end;
**********for循环 **循环变量自动累加**reverse反转***
begin
for v_nu in 1..100 loop
dbms_output.put_line(v_nu);
end loop;
end;
begin
for v_nu in reverse 1..100 loop
dbms_output.put_line(v_nu);
end loop;
end;
关键字: goto ,exit,continue,return
goto 类似break
exit 表示退出
continue 跳出此次循环
return
*********goto*** <<label>>后面不能直接写end************
ORA-06550: 第 14 行, 第 1 列:
PLS-00103: 出现符号 "END"在需要下列之一时:
( begin case
declare exit for goto if loop mod null raise return select
update while with <an identifier>
<a double-quoted delimited-identifier> <a bind variable> <<
continue close current delete fetch lock insert open rollback
savepoint set sql execute commit forall merge pipe purge
declare
v_flag number(1) :=0;
begin
for v_nu in reverse 1..100 loop
if v_nu =2 then
v_flag := 1;
goto label;
end if;
dbms_output.put_line(v_nu);
end loop;
<<label>>
dbms_output.put_line(v_flag);
end;
*********exit***退出这层循环******
begin
for v_nu in reverse 1..100 loop
if v_nu =2 then
exit;
end if;
dbms_output.put_line(v_nu);
end loop;
end;
declare
--打印1。。100 的质数
v_flag number(1) :=0;
begin
for c_i in 2..100 loop
for c_j in 2..sqrt(c_i) loop
if mod(c_i,c_j)=0 then
v_flag :=1;
exit;
end if;
end loop;
if v_flag =0 then
dbms_output.put_line(c_i);
end if;
v_flag :=0;
end loop;
end;
*********continue*********
begin
for v_nu in reverse 1..100 loop
if v_nu =2 then
continue;
end if;
dbms_output.put_line(v_nu);
end loop;
end;
*********return*********
begin
for v_nu in reverse 1..100 loop
if v_nu =2 then
return;
end if;
dbms_output.put_line(v_nu);
end loop;
end;
四、游标的使用类似java中的迭代器iterator
游标属性%FOUND 布尔型属性,当最近一次读记录时成功返回 , 则值为 TRUE ;%NOTFOUND 布尔型属性,与 %FOUND 相反;%ISOPEN 布尔型属性,当游标已打开时返回 TRUE ;%ROWCOUNT 数字型属性,返回已从游标中读取的记录数。
1. 显式游标处理
处理多行记录使用游标。
步骤4步,不能重复打开一个游标,关闭游标后可以重新打开游标提取数据。
定义游标->打开游标->提取游标数据->关闭游标
CURSOR cursor_name[(parameter[, parameter]…)] IS select_statement;
open cursor_name[(parameter,parameter...)]
fetch cursor_name into (varable_list|record_varable)
close cursor
示例:
declare
----查询ann_type为1 的消息名称
cursor ann_cursor is select ann_name from cafs_announcement where ann_type='1';
v_ann_name cafs_announcement.ann_name%type;
begin
open ann_cursor;
fetch ann_cursor into v_ann_name;
--遍历获取数据
loop
dbms_output.put_line(v_ann_name);
exit when ann_cursor%notfound;
fetch ann_cursor into v_ann_name;
end loop;
/*while ann_cursor%found loop
dbms_output.put_line(v_ann_name);
fetch ann_cursor into v_ann_name;
end loop;
*/
close ann_cursor;
end;
*******游标的使用:用for循环的话自动open和close以及提取数据************
declare
----查询ann_type为1 的消息名称
cursor ann_cursor is select ann_name from cafs_announcement where ann_type='1';
begin
for c in ann_cursor loop
dbms_output.put_line(c.ann_name);
end loop;
end;
2 带参数的游标
2.1 不使用for循环使用游标
CURSOR cursor_name(parameter_name datatype) IS select_statement; --只能制定类型,不能指定具体大小
OPEN cursor_name(参数值);-- open emp_cursor(v_sal=>1000,delete_flag =>'0');传值可以按照=>这样传值
FECTH cursor_name INTO variable,...;
CLOSE cursor_name;
declare
-- 更新人的名称
-- 0-5000 5%
-- 5000-10000 3%
-- 10000 -15000 2%
-- 15000 - 20000 1%
v_id employee.id%type;
v_emp_name employee.last_name%type;
v_sal employee.last_name%type;
v_temp number(14,2) :=0;
cursor emp_cursor(delete_flag char,v_sal number) is select id,last_name,sal from employee
where delete_flag=delete_flag and sal > v_sal;
begin
dbms_output.put_line(v_temp);
open emp_cursor(v_sal=>1000,delete_flag =>'0');
fetch emp_cursor into v_id,v_emp_name,v_sal;
while emp_cursor%found loop
if v_sal <5000 then v_temp:= 0.05;
elsif v_sal<10000 then v_temp:= 0.03;
elsif v_sal<15000 then v_temp:= 0.02;
else v_temp:= 0.01;
end if;
dbms_output.put_line(v_temp);
update employee set sal = sal*(1+v_temp) where id =v_id;
fetch emp_cursor into v_id,v_emp_name,v_sal;
end loop;
close emp_cursor;
end;
2.2 带参数的游标for循环传递参数方式,定义游标使用用default指定默认值
游标的 FOR 循环:
示例:PL/SQL 还允许在游标 FOR 循环语句中使用子查询来实现游标的功能。
3 隐藏游标
隐式游标属性SQL%FOUND 布尔型属性,当最近一次读记录时成功返回,则值为 TRUE;SQL%NOTFOUND 布尔型属性 , 与 %FOUND 相反;SQL %ROWCOUNT 数字型属性 , 返回已从游标中读取得记录数;SQL %ISOPEN 布尔型属性 , 取值总是 FALSE 。 SQL 命令执行完毕立即关闭隐式游标。
begin
update employee set gender = '1' where last_name= 'EEE';
if sql%notfound then dbms_output.put_line('查无此人'); end if;
end;
4 游标修改和删除操作
语法:SELECT . . . FROM … FOR UPDATE [OF column[, column]…] [NOWAIT]
五、异常错误处理
1 有三种类型的异常错误:
1 . 预定义 ( Predefined ) 错误ORACLE 预定义的异常情况大约有 24 个。对这种异常情况的处理,无需在程序中定义, 由 ORACLE 自动 将其引发 。2 . 非预定义 ( Predefined ) 错即其他标准的 ORACLE 错误。对这种异常情况的处理,需要用户在程序中定义,然后由 ORACLE 自动将 其引发。3 . 用户定义 (User_define) 错误程序执行过程中,出现编程人员认为的非正常情况。对这种异常情况的处理, 需要用户在程序中定义, 然后显式地在程序中将其引发 。
格式
EXCEPTIONWHEN first_exception THEN
WHEN second_exception THEN
WHEN OTHERS THEN
END;异常处理可以按任意次序排列 , 但 OTHERS 必须放在最后 .
2 预定义异常
示例:
declare
v_name cafs_announcement.ann_name%type;
begin
select ann_name into v_name from cafs_announcement where ann_type ='1';
exception
when too_many_rows then dbms_output.put_line('太多行');
when others then dbms_output.put_line('其他异常');
end;
3 非预定义 使用语句关联:pragma exception_init(异常情况,错误代码)
示例:
declare
v_name cafs_announcement.ann_name%type;
e_deletedid_exception exception;
pragma exception_init(e_deletedid_exception,-2292);
begin
delete from employee where employee_id = 100;
exception
when e_deletedid_exception then dbms_output.put_line('违反唯一约束');
when others then dbms_output.put_line('其他异常');
end;
4 用户自定义 raise抛出异常
declare
e_too_high_sal exception;
v_sal employee.sal%type;
begin
select sal into v_sal from employee where id =100;
if sal>10000 then
raise e_too_high_sal;
end if;
exception
when e_too_high_sal then dbms_output.put_line('工资太高了');
when others then dbms_output.put_line('其他异常');
end;
5 在 PL/SQL 中使用 SQLCODE, SQLERRM
create or replace noneditionable function get_salary(emp_count out number,v_delete varchar2)
return number
is
v_sum employee.sal%type;
begin
select sum(sal),count(sal) into v_sum,emp_count from employee where delete_flag = v_delete;
return v_sum;
exception
when no_data_found then
dbms_output.put_line('您要的数据不存在');
when others then
dbms_output.put_line(sqlcode||':'||sqlerrm);
end;
六、存储函数和过程
1 存储函数
语法如下:
CREATE [OR REPLACE] FUNCTION function_name
[ (argment [ { IN | IN OUT }] Type,
argment [ { IN | OUT | IN OUT } ] Type ]
[ AUTHID DEFINER | CURRENT_USER ]
RETURN return_type
{ IS | AS } <类型.变量的说明>
BEGIN
FUNCTION_body
EXCEPTION
其它语句
END;
示例
create or replace function get_salary(emp_count out number,v_delete varchar2)
return number
is
v_sum employee.sal%type;
begin
select sum(sal),count(sal) into v_sum,emp_count from employee where delete_flag = v_delete;
return v_sum;
exception
when no_data_found then
dbms_output.put_line('您要的数据不存在');
when others then
dbms_output.put_line(sqlcode||':'||sqlerrm);
end;
create or replace function hello_world
return varchar2
is
begin
return 'hello world';
end;
******带参数的存储函数********
create or replace function hello_world(v_logs varchar2)
return varchar2
is
begin
return 'hello world'||v_logs;
end;
*****带参数的存储函数************************
create or replace function hello_world(v_i number,v_j number)
return number
is
v_sum number:=0;
begin
v_sum := v_i+v_j;
return v_sum;
end;
***************
---查询保单号下的所有申请总和
create or replace function hello_world(v_policy varchar2)
return number
is
v_sum number :=0;
v_base_limit number :=0;
cursor limit_cursor is select base_limit from cafs_buyer_limit where policy_no = v_policy;
begin
open limit_cursor;
fetch limit_cursor into v_base_limit;
loop
v_sum := v_sum + v_base_limit;
exit when limit_cursor%notfound;
fetch limit_cursor into v_base_limit;
end loop;
close limit_cursor;
return v_sum;
end;
---查询保单号下的所有申请总和
create or replace function hello_world(v_policy varchar2)
return number
is
v_sum number(10) ;
v_base_limit number(10) ;
v_count number;
cursor limit_cursor is select base_limit from cafs_buyer_limit where policy_no = v_policy;
begin
select count(1) into v_count from cafs_buyer_limit where policy_no = v_policy;
dbms_output.put_line('数量:'||v_count);
v_sum:=0;
open limit_cursor;
fetch limit_cursor into v_base_limit;
while limit_cursor%found loop
if v_base_limit is null then
goto label;
end if;
v_sum := v_sum+v_base_limit;
<<label>>
fetch limit_cursor into v_base_limit;
end loop;
/* loop
if v_base_limit is null then
goto label;
end if;
v_sum := v_sum+v_base_limit;
dbms_output.put_line('总额:'||v_sum);
fetch limit_cursor into v_base_limit;
exit when limit_cursor%notfound;
<<label>>
dbms_output.put_line(v_sum);
end loop;*/
close limit_cursor;
dbms_output.put_line(v_sum);
return v_sum;
end;
1.1 执行存储函数方式两种
1 select test_fun from dual;
2 使用plsql块
declare
v_date date;
begin
v_date:=test_fun();
dbms_output.put_line(v_date);
end;
1.2 参数的传递,使用位子(v_num)或者名称(emp_count=>v_num,dept_id=>80)表示或者混合
1.3 可以使用DEFAULT关键字为输入参数指定默认 值。只 能为输入参数设置默认值,而不能为输入/输出参数设置默认值。
2 存储过程
2.1 语法
创建过程语法:
CREATE [OR REPLACE] PROCEDURE Procedure_name
[ (argment [ { IN | IN OUT }] Type,
argment [ { IN | OUT | IN OUT } ] Type ]
[ AUTHID DEFINER | CURRENT_USER ]
{ IS | AS } <类型.变量的说明>
BEGIN
<执行部分>
EXCEPTION
<可选的异常错误处理程序>
END;
示例:
create or replace procedure sum_sal_procedure(v_delete employee.delete_flag%type,v_sumsal out employee.sal%type)
is
begin
select sum(sal) into v_sumsal from employee where delete_flag = v_delete;
exception
when no_data_found then
dbms_output.put_line('您要的数据不存在');
when others then
dbms_output.put_line(sqlcode||':'||sqlerrm);
end;
示例:删除指定员工记录;
示例:插入员工记录;
2.2 调用存储过程 :使用 SHOW ERROR 命令来提示源码的错误位置;
方式一:select Proceure_name from dual; 只能执行简单的
方式二:plsql块执行
方式三:execute 执行
3 删除
1.删除过程
2.删除函数
3 删除触发器
7 触发器
触发器是许多关系数据库系统都提供的一项技术。在 ORACLE 系统里,触发器类似过程和函数,都有 声明,执行和异常处理过程的 PL/SQL 块。
1 DML 触发器
语法;
CREATE [ OR REPLACE ] TRIGGER trigger_name{ BEFORE | AFTER }{ INSERT | DELETE | UPDATE [ OF column [, column …]]}ON [schema.] table_name[ FOR EACH ROW ] ---是否逐行操作[ WHEN condition]trigger_body;
1.1 :NEW 和:OLD
示例:建立一个触发器, 当职工表 emp 表被删除一条记录时,把被删除记录写到职工表删除日志表中去。
七、 execute immediate用法详解(into赋值和using传参)
1 在PL/SQL运行DDL语句
begin execute immediate 'set role all'; end;
2. 给动态语句传值(USING 子句)
declare
l_depnam varchar2(20) := 'testing';
l_loc varchar2(10) := 'D?i';
begin
execute immediate 'insert into dept vals (:1, :2, :3)'
using 50, l_depnam, l_loc;
commit;
end;
3. 从动态语句检索值(INTO子句)
declare
l_cnt varchar2(20);
begin
execute immediate 'select count(1) from emp'
into l_cnt;
dbms_output.put_line(l_cnt);
end;
八、包的创建和应用
一个包由两个分开的部分组成:
1 包定义的语法如下:
创建包定义 :CREATE [ OR REPLACE ] PACKAGE package_name[AUTHID {CURRENT_USER | DEFINER}]{ IS | AS }[ 公有数据类型定义 [ 公有数据类型定义 ]…][ 公有游标声明 [ 公有游标声明 ]…][ 公有变量、常量声明 [ 公有变量、常量声明 ]…][ 公有子程序声明 [ 公有子程序声明 ]…]END [package_name];其中: AUTHID CURRENT_USER 和 AUTHID DEFINER 选项说明应用程序在调用函数时所使用的权限模式,它们与CREATE FUNCTION 语句中 invoker_right_clause 子句的作用相同。
2 创建包主体:
CREATE [ OR REPLACE ] PACKAGE BODY package_name { IS | AS }[ 私有数据类型定义 [ 私有数据类型定义 ]…][ 私有变量、常量声明 [ 私有变量、常量声明 ]…][ 私有子程序声明和定义 [ 私有子程序声明和定义 ]…][ 公有游标定义 [ 公有游标定义 ]…][ 公有子程序定义 [ 公有子程序定义 ]…]BEGINPL/SQL 语句END [package_name];
其中:在包主体定义公有程序时,它们必须与包定义中所声明子程序的格式完全一致
3 示例
1 创建的包为 demo_pack, 该包中包含一个记录变量 DeptRec、两个函数和一个过程。
CREATE OR REPLACE PACKAGE demo_pack
IS
DeptRec dept%ROWTYPE;
FUNCTION add_dept(dept_no NUMBER, dept_name VARCHAR2, location VARCHAR2)
RETURN NUMBER;
FUNCTION remove_dept(dept_no NUMBER)
RETURN NUMBER;
PROCEDURE query_dept(dept_no IN NUMBER);
END demo_pack;
//包主体的创建方法,它实现上面所声明的包定义
CREATE OR REPLACE PACKAGE BODY demo_pack
IS
FUNCTION add_dept
(dept_no NUMBER, dept_name VARCHAR2, location VARCHAR2)
RETURN NUMBER
IS
empno_remaining EXCEPTION;
PRAGMA EXCEPTION_INIT(empno_remaining, -1);
/* -1 是违反唯一约束条件的错误代码 */
BEGIN
INSERT INTO dept VALUES(dept_no, dept_name, location);
IF SQL%FOUND THEN
RETURN 1;
END IF;
EXCEPTION
WHEN empno_remaining THEN
RETURN 0;
WHEN OTHERS THEN
RETURN -1;
END add_dept;
FUNCTION remove_dept(dept_no NUMBER)
RETURN NUMBER
IS
BEGIN
DELETE FROM dept WHERE deptno=dept_no;
IF SQL%FOUND THEN
RETURN 1;
ELSE
RETURN 0;
END IF;
EXCEPTION
WHEN OTHERS THEN
RETURN -1;
END remove_dept;
PROCEDURE query_dept(dept_no IN NUMBER)
IS
BEGIN
SELECT * INTO DeptRec FROM dept WHERE deptno=dept_no;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('数据库中没有编码为'||dept_no||'的部门');
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE('程序运行错误!请使用游标');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLCODE||’----‘||SQLERRM);
END query_dept;
BEGIN
Null;
END demo_pack;
九、merge into using on语句写法及作用
MERGE INTO 目标表 a
USING 源表 b
ON (a.字段1 = b.字段2 and a.字段n = b.字段n)
WHEN MATCHED THEN
UPDATE SET a.新字段 = b.字段 WHERE 限制条件
WHEN NOT MATCHED THEN
INSERT (a.字段名1,a.字段名n) VALUES(b.字段值1, b.字段值n)WHERE 限制条件123456789