Oracle数据库—— 存储过程与函数的创建
一、涉及内容
1.掌握存储过程与函数的概念。
2.能够熟练创建和调用存储过程与函数。
二、具体操作
1.创建存储过程,根据职工编号删除scott.emp表中的相关记录。
(1)以scott 用户连接数据库,然后为system 用户授予delete 权限。
语句:
connect scott/tiger;
grant delete on emp to system;
截图:

(2)以system 用户连接数据库,创建存储过程。
语句:
connect system/orcl1234; create or replace procedure delete_emp
(id scott.emp.empno%type)
is
begin
delete from scott.emp where empno=id;
exception
when others then
dbms_output.put_line('errors');
end;
截图:

(3)system 用户调用delete_emp存储过程。
语句:execute delete_emp(7369);
截图:

(4)scott 用户调用delete_emp存储过程。
语句:
grant execute on delete_emp to scott;
connect scott/tiger;
execute system.delete_emp(7369);
截图:

2.创建存储过程,根据职工编号修改scott.emp表中该职工的其他信息。
(1) 创建新用户,并授予权限。
connect system/orcl1234; create user u1
identified by abcdef; grant create session,
create procedure to u1; grant select,update on scott.emp to u1;
(2) 以新用户连接数据库,创建存储过程。
语句:
connect u1/abcdef; CREATE OR REPLACE PROCEDURE update_emp
(no IN scott.emp.empno%TYPE,--引用emp表中的某字段的数据类型,必须对该表具有select权限
name IN scott.emp.ename%TYPE DEFAULT NULL,
job1 IN scott.emp.job%TYPE DEFAULT NULL,
mgr1 IN scott.emp.mgr%TYPE DEFAULT NULL,
hiredate1 scott.emp.hiredate%TYPE DEFAULT NULL,
salary scott.emp.sal%TYPE DEFAULT NULL,
comm1 scott.emp.comm%TYPE DEFAULT NULL,
deptno1 scott.emp.deptno%TYPE DEFAULT NULL
)
IS
BEGIN
if name is not null then
update scott.emp set ename=name where empno=no;
end if;
if job1 is not null then
update scott.emp set job=job1 where empno=no;
end if;
if mgr1 is not null then
update scott.emp set mgr=mgr1 where empno=no;
end if;
if hiredate1 is not null then
update scott.emp set hiredate=hiredate1 where empno=no;
end if;
if salary is not null then
update scott.emp set sal=salary where empno=no;
end if;
if comm1 is not null then
update scott.emp set comm=comm1 where empno=no;
end if;
if deptno1 is not null then
update scott.emp set deptno=deptno1 where empno=no;
end if;
EXCEPTION
WHEN others THEN
rollback;
END;
/
截图:


(3) u1调用update_emp 过程。
语句: exec update_emp(7369,salary=>2000);
截图:

3.创建存储过程,根据指定的职工编号查询该职工的详细信息。
(1)创建存储过程。
语句:
connect scott/tiger; create or replace procedure select_emp
(no in scott.emp.empno%type,
emp_information out varchar2)
is
r scott.emp%ROWTYPE;
begin
select * into r from scott.emp where empno=no;
emp_information:=emp_information||r.ename||' '||r.job||' '||r.sal||' '||r.mgr||
' '||r.hiredate||' '||r.comm||' '||r.deptno;
exception
when no_data_found then
emp_information:='No person!';
when others then
emp_information:='Error!';
End;
/
截图:

(2)调用存储过程。
语句:
set serveroutput on
declare
info varchar2(50);
begin
select_emp(7369,info);
dbms_output.put_line(info);
end;
/
截图:

4.创建函数,根据给定的部门编号计算该部门所有职工的平均工资。
(1)创建函数。
语句:
create or replace function avg_sal
(no scott.emp.deptno%type)
return number
is
avgsal number(7,2);
begin
select avg(sal) into avgsal from scott.emp where deptno=no;
if avgsal is not null then --因为上面的语句不触发异常,因此用if语句判断是否查询成功
return avgsal;
else
avgsal:=-1;
return avgsal;
end if;
end avg_sal;
/
截图:

(2)调用函数。
语句:
begin
dbms_output.put_line(avg_sal(&deptno));
end;
截图:

(选择题)
- 以下哪种程序单元必须返回数据?( A )
A.函数 B.存储过程 C.触发器 D.包
2.当建立存储过程时,以下哪个关键字用来定义输出型参数?( C )
A.IN B.PROCEDURE C.OUT D.FUNCTION
3.下列哪个语句可以在SQL*Plus中直接调用一个存储过程?( B )
A.RETURN B.EXEC C.SET D.IN
4.下面哪些不是存储过程中参数的有效模式?( D )
A.IN B.OUT C.IN OUT D.OUT IN
5.函数头部中的RETURN语句的作用是什么?( A )
A.声明返回的数据类型
B.调用函数
C.调用过程
D.函数头部不能使用RETURN语句
(编程题)
- 根据以下要求编写存储过程:输入部门编号,输出scott.emp 表中该部门所有职工的职工编号、姓名、工作岗位。
(1)授予system用户对scott.emp具有显示的查询权限。

(2)创建存储过程
语句:
create or replace procedure pro_depart
(no in scott.emp.deptno%type)
is
cursor c1 is select * from scott.emp where deptno=no;
begin
dbms_output.put_line('编号 姓名 工作岗位');
for rec in c1
loop
dbms_output.put_line(rec.empno||' '||rec.ename||' '||rec.job);
end loop;
end;
截图:

(3)执行存储过程
语句: execute pro_depart(20);
截图:

2.根据以下要求编写函数:将scott.emp 表中工资低于平均工资的职工工资加上200,并返回修改了工资的总人数。
(1)授予system用户对scott.emp具有修改的权限。

(2)创建函数
语句:
conn system/orcl1234; create or replace function fun_sal
return number
is
cursor c2 is select * from scott.emp for update;
rows number default 0;
avg_sal number(7,2);
begin
select avg(sal) into avg_sal from scott.emp;
for rec in c2
loop
if rec.sal< avg_sal then
update scott.emp set sal=sal+200 where current of c2;
rows:=rows+1;
end if;
end loop;
return rows;
end;
截图:

(3)调用函数
语句:
begin
dbms_output.put_line('修改了工资的总人数是: '||fun_sal);
end;
截图:

(简答题)
创建与调用存储过程或函数时,应事先授予哪些权限?
答:1.首先创建存储过程自身需要的权限,即应授予create procedure系统权限。
2.用户调用其他用户所创建的存储过程时,应事先授予对该过程的execute权限。
3.如果对某表进行增、删、查、改的操作时,应授予insert、delete、update、select的显示权限。
(补充练习题)
1. 编写函数get_salary,根据emp表中的员工编号,获取他的工资。输入参数为员工编号,如果找到该员工,屏幕显示已找到的信息,函数返回值为该员工的工资。如果找不到,捕获并处理异常,函数返回值为0。函数创建成功后,调用该函数查看效果。
(1)创建函数
语句:
create or replace function get_salary
(no in scott.emp.empno%type)
return number
is
salary scott.emp.sal%type;
begin
select sal into salary from scott.emp where empno=no;
return salary;
exception
when others then
return 0;
end;
截图:

(2)调用函数
语句:
begin
dbms_output.put_line('该员工工资是:'||get_salary(7369));
end;
截图:

语句:
begin
dbms_output.put_line('该员工工资是:'||get_salary(2000));
end;
截图:

2. 编写函数get_cnt,根据输入参数部门编号,输出参数输出该部门的人数,返回值是该部门的工资总和。如果如果找不到,捕获并处理异常,函数返回值为0。函数创建成功后,调用该函数查看效果。
(1)创建函数
语句:
create or replace function get_cnt
(no in scott.dept.deptno%type,
cnt out number )
return number
is
salary_sum number(7,2);
begin
select sum(sal) into salary_sum from scott.emp where deptno=no;
select count(*) into cnt from scott.emp where deptno=no;
return salary_sum;
exception
when others then
return 0;
end;
截图:

(2)调用函数
语句:
var salary_sum number;
var cnt number;
exec :salary_sum:=get_cnt(30,:cnt);
截图:

3.编写存储过程DelEmp,删除emp表中指定员工记录。输入参数为员工编号。如果找到该员工,则删除他的记录,并在屏幕显示该员工被删除。如果没找到,则使用自定义异常处理。存储过程定义成功后,调用该存储过程查看结果。
(1)以scott 用户连接数据库,然后为system 用户授予delete 权限。
语句:
connect scott/tiger;
grant delete on emp to system;
截图:

(2)以system 用户连接数据库,创建存储过程。
语句:
connect system/orcl1234; create or replace procedure DelEmp
(no scott.emp.empno%type)
is
no_emp exception;
cnt number;
begin
select count(*) into cnt from scott.emp where empno=no;
if cnt=0 then
raise no_emp;
end if;
delete from scott.emp where empno=no;
dbms_output.put_line(no||'号员工已经被删除完毕!');
exception
when no_emp then
dbms_output.put_line('抱歉!没有找到'||no||'号员工!');
end;
/
截图:

(3)调用存储过程。
语句:exec DelEmp(2000);
截图:

4. 编写存储过程QueryEmp,查询指定员工记录;输入参数为员工编号,输出参数是员工的姓名和工资。如果找到该员工,在屏幕显示该员工已经查到。如果没找到,则捕获异常并处理。存储过程定义成功后,调用该存储过程查看结果。
(1)创建过程
语句:
CREATE OR REPLACE PROCEDURE QueryEmp
(no IN scott.emp.empno%TYPE,
name OUT scott.emp.ename%TYPE,
salary OUT scott.emp.sal%TYPE)
IS
BEGIN
SELECT ename,sal into name,salary FROM scott.emp WHERE empno=no;
dbms_output.put_line('找到员工!');
EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('该职工不存在!');
END;
/
截图:

(2)执行过程
语句:
DECLARE
emp_name scott.emp.ename%TYPE;
emp_salary scott.emp.sal%TYPE;
BEGIN
QueryEmp(7788,emp_name,emp_salary); --调用存储过程
IF emp_name IS NOT NULL THEN --如果该职工存在,则输出
dbms_output.put_line('姓名是:'||emp_name|| ' 工资是:'||emp_salary);
END IF;
END;
亦可:exec QueryEmp(7788,:ename,:sal);
截图:

Oracle数据库—— 存储过程与函数的创建的更多相关文章
- oracle数据库存储过程中NO_DATA_FOUND不起作用解决
oracle数据库存储过程中NO_DATA_FOUND不起作用 1.首先创建一个表lengzijiantest,表中只有一个字段f_id ? 1 2 3 4 5 [cpp] CREATE TABLE ...
- oracle数据库存储过程中的select语句的位置
导读:在oracle数据库存储过程中如果用了select语句,要么使用"select into 变量"语句要么使用游标,oracle不支持单独的select语句. 先看下这个存储过 ...
- 编程开发之--Oracle数据库--存储过程和存储函数(2)
上一小结我们简单介绍了存储过程和存储函数,对存储过程和存储函数有了一个基本的了解,接下来介绍在java程序中如何调用我们创建的存储过程和存储函数 1.在应用程序中调用我们的存储过程 创建一个简单的Ja ...
- 编程开发之--Oracle数据库--存储过程在out参数中使用光标(3)
在本系列学习随笔中的第2节我们留下了2个问题,我们现在讨论在out参数中使用光标. 1.要在out参数中使用光标,我们需要申明一个包的结构,包的结构分为包头和包体,包头只负责申明,包体只负责实现.包头 ...
- oracle数据库之存储函数和过程
一.引言 ORACLE 提供可以把 PL/SQL 程序存储在数据库中,并可以在任何地方来运行它.这样就叫存储过程或函数.过程和函数统称为 PL/SQL 子程序,他们是被命名的 PL/SQL 块 ...
- java下实现调用oracle的存储过程和函数
在Oracle下创建一个test的账户,然后 1.创建表:STOCK_PRICES --创建表格 CREATE TABLE STOCK_PRICES( RIC VARCHAR() PRIMARY KE ...
- Oracle procedure存储过程/function函数
--函数的创建 create function func1(dno number) return NUMBER--必须带有返回值 is v_max number;--定义返回值 begin selec ...
- Java代码调用Oracle的存储过程,存储函数和包
Java代码调用存储过程和存储函数要使用CallableStatement接口 查看API文档: 上代码: java代码调用如下的存储过程和函数: 查询某个员工的姓名 月薪 职位 create or ...
- 【学习】java下实现调用oracle的存储过程和函数
在oracle下创建一个test的账户,然后按一下步骤执行: 1.创建表:STOCK_PRICES --创建表格CREATETABLE STOCK_PRICES( RIC VARCHAR(6) PRI ...
随机推荐
- 树莓派安装kali后的简单配置
树莓派可以说是极客的最爱,可以根据不同的需求去做定制. 前文<使用树莓派和kali Linux打造便携式渗透套件>讲了一些使用树莓派的基础,主要侧重于将树莓派当作一个物理后门使用.我则更喜 ...
- php大力力 [003节]php在百度文库的几个基础教程mac环境下文本编辑工具
2015-08-22 php大力力003.mac环境下文本编辑工具 在windows下,使用notepad特别多.在mac下使用“备忘录”app,word,反而没有存储过txt后缀等不同文本. mac ...
- 百度VS高德:LBS开发平台ios SDK对比评测
随着iPhone6手机的热销,目前的iOS应用开发市场也迎来了全盛时期.据了解,目前市面上已有的iOS应用基本覆盖了购物.上门服务.用车服务.娱乐等行业.而在这些iOS应用中,内置LBS服务的应用占大 ...
- 总结PowerShell的常用命令
命令1: #连接Azure订阅账户 Add-AzureAccount #获取所有在连接着的Azure订阅 Get-AzureAcount Get-AzureSubscription #设置当前的Azu ...
- Java学习第五天
一.内存分析 内存分析:指数据的存储,理解程序执行过程,运行期的行为,不是编译期. 分类 栈: 方法栈存储方法的局部变量|形参后进先出 堆: 对象堆存储new的对象散列存储 方法区: 特殊的堆,类方法 ...
- 4 Values whose Sum is 0
Time Limit:15000MS Memory Limit:228000KB 64bit IO Format:%I64d & %I64u Submit Status D ...
- Java单例类的简单实现
对于java新手来说,单例类给我的印象挺深,之前一道web后台笔试题就是写单例类.*.*可惜当时不了解. 在大部分时候,我们将类的构造器定义成public访问权限,允许任何类自由创建该类的对象.但在某 ...
- Linux下使用fdisk发现磁盘空间和使用mount挂载文件系统
若在安装Linux系统时没有想好怎么使用服务器,开始时只分了一部分给根目录.后面需要再使用时,可以通过几下一步进行分区和挂载文件系统. 看磁柱数使用情况 fdisk -l Disk /dev/sda: ...
- 最最实用的30个Linux命令!
本文中将介绍一些实用又常用的Linux或Unix命令,这些是Linux系统管理员们平常使用的命令.本文不是什么完整列表,而是简要地列出了需要时派得上用场的命令,下面开始逐一介绍如何使用这些命令并附有示 ...
- codeforces 192 c
link: http://codeforces.com/contest/330/problem/C broute force but you must be careful about some tr ...