函数

==函数== 带有括号,带有返还值(一个返回值)

==普通函数== Oracle系统自带的函数

函数的创建

语法
create or replace function 函数名(参数 参数类型 数据类型) return 返回值的数据类型 is/as
–声明部分
begin
执行语句;
return 返回值;
end;

调用方法
1.select 函数名() from 表名; ==看不到打印与出参==

  1. exec 函数名/execute 函数名 ==只能在命令提示行中执行—缺点看不到打印结果==
  2. begin end 程序块调用
    declare
    声明一个变量,用来承接返回值 ==类型要与return返回值的数据类型一致==
    begin
    变量名 := 函数名(参数);
    end;

无参数的函数

例:定义一个函数,打印一串文字

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
create or replace function fun_wenzi return varchar2 is
--声明部分
begin
dbms_output.put_line('今天上午十一点才开始讲课!');
return '你猜输出哪一句';
end;


---调用
declare
v_a varchar2(50);--声明一个变量用来接收返回值
begin
v_a := fun_wenzi();--把返回值赋值给变量
dbms_output.put_line(v_a);--打印变量接收到的值
end;

select fun_wenzi() from dual;---使用函数输出返回值

begin
fun_wenzi();---报错,提示不是存储过程
end;

--可以在块中直接写return
create or replace function fun_wenzi return varchar2 is
--声明部分
begin
return '这是一个没用的函数!';
end;

select fun_wenzi(job) from emp;--没有入参出参时,不具备处理表中字段的能力,只能返回一个定好的返回值

入参跟出参的写法

写一个存储过程,传入一个员工编号,传出一个员工姓名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
create or replace function fun_emp(xm out varchar2,no1 in number)return varchar2 is
v_gangwei varchar2(100);
begin
select ename,job into xm,v_gangwei from emp where empno = no1;
return v_gangwei;
end;


declare
xm varchar2(100);
v_a varchar2(100);
begin
v_a := fun_emp(xm,7788);--与存储过程的参数需要一一对应
dbms_output.put_line(xm);
dbms_output.put_line(v_a);
end;

select fun_emp(1,empno) from emp;---对于有出参的函数,不能用select语句调用

创建一个函数,传入员工编号,返回员工岗位

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
create or replace function fun_emp(no1 in number,gangwei out varchar2,shijian out date)return varchar2 is
---入参与出参都可以有多个,返回值只能有一个
v_gangwei varchar2(100);
v_xinzi number(7);
begin
select job,hiredate into gangwei,shijian from emp where empno = no1;
return ('v_xinzi');---写两个retrun的时候,函数不会报错,但只会返还第一个return的值
return (v_gangwei);
end;

select fun_emp(empno,gangwei,xinzi) from emp;--select 语句不具备接收参数的能力(有出参不能用select)

declare
gangwei varchar2(100);
shijian date;
v_a varchar2(100);
begin
v_a := fun_emp(7788,gangwei,shijian);---变量只能接收到函数的返回值
dbms_output.put_line(gangwei||shijian);
dbms_output.put_line(v_a);
end;

in out

例题:传入一个员工编号传出一个员工薪资,返回员工姓名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
create or replace function fun_a(xmxz in out number) return varchar2 is
v_emp emp%rowtype;
begin
select * into v_emp from emp where empno=xmxz;
xmxz:= v_emp.sal;
return v_emp.ename;
end;

declare
xz number :=7788;
a varchar2(10);
begin
dbms_output.put_line(xz);
a := fun_a(xz);
dbms_output.put_line(xz);
dbms_output.put_line(a);
end;

使用全类型

例题:传入一个员工编号传出一个员工姓名,返回一个薪资

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
create or replace function fun_b(xmxz in out emp%rowtype) return number is
--因为一个值需要具备多种类型,所以我们使用%rowtype
v_emp emp%rowtype;
begin
select * into v_emp from emp where empno = xmxz.empno;--需要用全类型中-empno列的类型区匹配empno
xmxz.ename := v_emp.ename;--需要传出姓名列,所以用全类型中的姓名列的类型去接收赋值
return v_emp.sal;--返还薪资
end;

declare
a emp%rowtype;--需要传入number类型,接收varchar2类型,所以声明一个全类型
b number;--接收返回值,声明返回值的类型
begin
a.empno := 7788;---传入empno类型的值,所以用全类型.empno去接收赋值
b:= fun_b(a);
dbms_output.put_line(a.empno||a.ename);--打印传出的ename列类型
dbms_output.put_line(b);
end;

return游标类型

例题:传入一个部门编号,返回一个游标类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
create or replace function fun_c(bm in number) return sys_refcursor is
cur sys_refcursor;
begin
open cur for select * from emp where deptno = bm;
return cur;
end;

declare
cur_a sys_refcursor;
v_emp emp%rowtype;
begin
cur_a := fun_c(&部门编号);
loop
fetch cur_a into v_emp;
exit when cur_a%notfound;
dbms_output.put_line(v_emp.ename||v_emp.sal);
end loop;
close cur_a;
end;

例题:创建一个函数,当我们传入一个字符串后,返回一个首字母大写,第三个字母大写,其他字母小写的字符串

1
2
3
4
5
6
7
8
create or replace function fun_0830_a(a varchar2) return varchar2 is
b varchar2(100);
begin
b:=upper(substr(a,1,1))||lower(substr(a,2,1))||upper(substr(a,3,1))||lower(substr(a,4));
return b;
end;

select fun_0830_a(ename) from emp;

函数与存储过程的区别

  1. 存储过程的主要作用是入参与出参,函数的主要作用是入参与返回值(只有一个)
  2. 存储过程一般是作为一个独立的部分来执行(begin and 调用),函数更多作为查询语句来使用(select 语句中使用)
  3. 存储过程可以没有参数,函数可以没有参数,但必须有且只有一个返回值。
  4. 函数的入参比较常见,但出参基本不用(需要出参时使用函数不如使用存储过程)