Oracle学习笔记

一、Oracle的表空间

Oracle数据库开创性地提出了表空间的设计理念,这为Oracle数据库的高性能做出了不可磨灭的贡献。可以这么说,Oracle中很多优化都是基于表空间的设计理念而实现的。
ORACLE数据库被划分成称作为表空间 [1] 的逻辑区域——形成ORACLE数据库的逻辑结构。一个ORACLE数据库能够有一个或多个表空间,而一个表空间则对应着一个或多个物理的数据库文件。表空间是ORACLE数据库恢复的最小单位,容纳着许多数据库实体,如表、视图、索引、聚簇、回退段和临时段等。

1、Oracle中表空间的作用:

1.决定数据库实体的空间分配

2.设置数据库用户的空间份额

3.控制数据库部分数据的可用性;

4.分布数据于不同的设备之间以改善性能;

5.备份和恢复数据。

一个数据库可以包含多个表空间(主要用于存放表的区域),一个表空间只能属于一个数据库。同样,一个表空间内可以包含多个数据文件,但一个数据文件只能属于一个表空间。Oracle中至少存在一个表空间,即SYSTEM表空间,系统中默认存在的表空间System、Sysaux、users、undotbs1、Example、TEMP

2、表空间操作

注意操作表空间需要使用dba用户或拥有dba用户授予的权限
1.查看表空间(需要dba权限)

select * from v$tablespace;

2.查看表空间中的数据文件

select file_name,tablespace_name from dba_data_files;

3.创建表空间

create tablespace test_data  
datafile 'test_data01.dbf '  
size 32m  
autoextend on  
next 32m 
maxsize 2048m  
extent management local;

4.删除表空间

drop tablespace test_data including contents and datafiles;

5.创建临时表空间

create temporary tablespace test_temp 
tempfile 'mp01.dbf' 
size 32m 
autoextend on next 32m 
maxsize 2048m 
extent management local;

临时表空间用来管理数据库排序操作以及用于存储临时表、中间排序结果等临时对象。
1、局部临时表(#开头)只对当前连接有效,当前连接断开时自动删除。
2、全局临时表(##开头)对其它连接也有效,在当前连接和其他访问过它的连接都断开时自动删除。
3、不管局部临时表还是全局临时表,只要连接有访问权限,都可以用drop table #Tmp(或者drop table ##Tmp)来显式删除临时表。

扩展:
同义词
同异词是数据库对象的一个别名,经常用于简化对象访问和提高对象访问的安全性。同义词有私有同义词和公用同义词。私有同义词只供创建它的用户使用,公用同义词可供数据库所有对象使用。

创建同义词

create [public] synonym 同义词名称 for [username.]objectName

删除同义词

drop [public] synonym 同义词;

查看同义词

select * from dba_synonyms/user_synonyms;

二、用户权限管理

引言:学会在Oracle中如何创建表空间后,就要学会怎么去给用户分配这些表空间的使用,即给用户使用、查看的权限。注意以下操作需要使用sys或system用户权限

用户管理
1.创建用户

create user username identified by password;

2.创建并给用户分配表空间

create user username
identified by 1223456
default tablespace tablespacename
temporary tablespace temp_tablespacename;

3.删除用户

# 用户下没有任何对象
drop user xxx
# 用户下存在对象,必须加cascade删除用户下所有对象。
drop user xxx cascade

4.锁定/解锁用户(可以不删除用户,拒绝用户连接)

alter user username account lock/unlock;

5.修改用户密码

# 如果忘记了普通用户的密码,也可在这里直接修改。
alter user username identified by password;

6.查看当前用户的相关信息(用户名、默认表空间…)

select * from user_users;

一个用户可以使用一个或多个表空间,一个表空间也可以供多个用户使用。用户与表空间没有隶属关系。

权限(privilege)管理
用户权限有系统权限和对象权限两种。系统权限即数据库的使用权限,只能由DBA用户(sys,system)授出。用户权限包括:

  • dba:拥有全部特权,是系统最高权限。
  • resource:拥有访问数据库对象的权限。
  • connect:拥有连接数据库的权限,但不可以访问数据库对象。

对象权限是某种权限用户对其他用户的表或视图的存取权限,它允许用户对一些特定的对象,进行更新、插入等操作。对象权限包括:

  • select ,update,insert ,alter ,alter ,index,delete,all(所有权限),execute(执行存储过程的权限)

1.给用户授予系统权限 √ connect,resource…

grant privilege to username

2.给用户授予对象权限 √select ,update,insert…

grant select on tablename to username

3.撤销用户权限

# 撤销系统权限
revoke connect from username;
# 撤销对象权限
revoke select on tablename from username

4.给用户授予系统权限并拥有授予其他用户的权利。例如授权给A ,A可以授权给B。撤销A的权限后,B不会受到影响

# with admin option只能用于系统权限授权
grant privilege to username with admin option

5.给用户授予对象权限并拥有授权给其他用户的权利。撤销权限级联,如给A授权后,A授权给B。撤销A的权限后,B的权限也会撤销。注意不能直接撤销B的权限!

# with grant option只能用于给对象权限授权
grant select on tablename to username with grant option

角色管理
角色就是一组权限,更加方便权限管理。例如给多个用户赋予一个角色role0,那么就可以通过修改这个角色的权限达到批处理的功能。
1.创建角色

create role 角色名

2.给角色授权

grant 系统权限 to 角色
grant 对象权限 on 对象 to 角色

3.撤销角色权限

revoke 系统权限 from 角色
revoke 对象权限 on 对象 from 角色

4.将角色赋予用户

grant 角色 to 用户

查看权限

# 查看用户所有系统权限
select * from user_sys_privs

# 查看用户所属角色
select * from user_role_privs;

# 角色有哪些系统权限
select * from role_sys_privs;

# 角色有哪些对象权限
select * from role_tab privs;

三、PLSQL编程

简介:PL/SQL (Procedure Language & Structured Query Language),PL/SQL是Oracle数据库对SQL语句的扩展。它在普通SQL语句的使用上增加了编程语言的特点,所以PL/SQL就是把数据操作和查询语句组织在PL/SQL代码的过程性单元中,通过逻辑判断、循环等操作实现复杂的功能或者计算的程序语言。
简单来说就是:PLSQL能够帮助我们实现SQL语句的复用,还可以在中间添加逻辑代码。

PL/SQL具有的特点:
⒈能够使一组SQL语句的功能更具模块化程序特点;(模块化就是可以实现复用)
⒉采用了过程性语言控制程序的结构;
⒊可以对程序中的错误进行自动处理,使程序能够在遇到错误的时候不会被中断;
⒋具有较好的可移植性,可以移植到另一个Oracle数据库中;
⒌集成在数据库中,调用更快;
⒍减少了网络的交互,有助于提高程序性能;
7 运行错误的可处理性;
8 提供大量内置程序包;

注意:在 PL/SQL中只能用 SQL语句中的 DML 部分,不能用 DDL 部分,如果要在PL/SQL中使用DDL(如CREATE table 等)的话,只能以动态的方式来使用。

DML(Data Manipulation Language)数据操作语言,如SELECT,UPDATE,INSERT,DELETE。
DDL(Data Definition Language)数据定义语言,如CREATE、ALTER、DROP。
DCL(Data Control Language)数据控制语言,如Commit,Rollback,Grant。

PL/SQL程序由三个块组成,即声明部分、执行部分、异常处理部分。
示例:

declare
	--声明语句;
begin
	--执行语句;
exception
	--异常处理
end;

声明变量与赋值

1.声明变量的格式: 变量名 数据类型; i int := 10;
2.变量类型:char、varchar2、number、long、dateboolean

3.变量赋值:
(1)普通赋值方式:a := 10;2)数据库赋值(使用select into):
DECLARE 
  n VARCHAR2(20); 
BEGIN  
  SELECT ename INTO n FROM emp 
  WHERE empno = 7900;
  dbms_output.put_line(n);
END;3)数据库赋值(使用insert/update/deletereturning赋值)
declare 
  n varchar
  row_id rowid
begin
  insert into emp(empno,ename) values(1234,'孙杨')
  returning rowid,ename into row_id,n;
end;4)复合数据类型——记录类型
记录类型是将逻辑相关的分离的基本数据类型的变量组合成一个类型,相当于封装了不同类的对象类型。
declare
  type student is record(
    sid_ int
    name_ varchar2,
    birth date
  )
  stu student;
begin
  select empno,ename,hiredate into stu from emp 
  where empno=7900;
end;5)复合数据类型——表类型
表类型是对记录类型的扩展。它可以处理多行记录,类似于高级中的二维数组,使得可以在PL/SQL中模仿数据库中的表。
使用表格类型的优点:
所引用的数据库列的数据类型可以不必知道。
所引用的数据库列的数据类型可以实时改变,容易保持一致,也不用修改PL/SQL程序。
例1:记录某个表字段类型使用%type
empno_ emp.empno%TYPE2:记录某个表行(所有字段的类型)使用%rowtype
declare
  r_emp emp%ROWTYPE;
begin
  select * into r_emp from emp
  where empno=7900
  dbms_output.put_line(r_emp.ename);
end;

条件语句

1.if条件语句
declare
  salary emp.sal%type;
  empno_ emp.empno%type;
begin
  empno_ := &请出入员工编号;
  select sal into salary from emp where empno = empno_;
  if salary > 2000 then
    ...
  elsif salary between 1000 and 2000 then
    ...
  else
    ...
  end if;
end;
2.case条件语句
例1caseSQL语句中使用
select case grade 
  when 1 then '一级'
  when 2 then '二级'
  else '更高级'
  end
from salgrade;2case在pl/sql中使用
DECLARE
  g VARCHAR2(20);
  v INT;
BEGIN
  v := &请输入数字;
  g := CASE v WHEN 1 THEN '一级'
    WHEN 2 THEN '二级'
      ELSE '错误'
        END;
  dbms_output.put_line(g);
END;

循环

1.简单循环 loop 
declare
  i int :=0;
begin
  loop
    i:=i+1;
    exit when i = 100; -- 作用类似java循环中break语句
  end loop;
  dbms_output.put_line(i);
end;

2.while循环
declare
  i int :=0;
begin
  while i<100 loop --判断条件写在前面
    i:=i+1; 
  end loop;
  dbms_output.put_line(i);
end;

3.数字式循环 for in ..loop
DECLARE
  i INT := 0;
BEGIN
  FOR i IN REVERSE 0..100 LOOP
  END LOOP;
  dbms_output.put_line(i);
END;
-- Reverse为可选参数

游标(cursor)
游标提供了一种对从表中检索出的数据进行操作的灵活手段,就本质而言,游标实际上是一种能从包括多条数据记录的结果集中每次提取一条记录的机制
在PL/SQL块中执行SELECT、INSERT、DELETE和UPDATE语句时,ORACLE会在内存中为其分配上下文区(Context Area),即缓冲区。游标是指向该区的一个指针
1.显示游标与隐式游标
显式游标:
显式游标主要是用于对查询语句的处理,尤其是在查询结果为多条记录的情况下
隐式游标:
对于非查询语句,如修改、删除操作,则由ORACLE系统自动设置游标

2.显示游标处理步骤
1)定义/声明游标
2)打开游标
3)提取游标数据
4)关闭游标

案例1: 游标基本使用

DECLARE
  CURSOR c IS SELECT * FROM dept; -- 1定义用于遍历查询结果的游标
  v_dept dept%ROWTYPE;
BEGIN
  OPEN c; -- 2打开游标
  FETCH c INTO v_dept; -- 3提取游标数据
  WHILE c%FOUND LOOP  --判断上一次提取游标操作是否成功
    dbms_output.put_line(v_dept.dname); 
    FETCH c INTO v_dept
  END LOOP;
  CLOSE c;--4关闭游标
END;

案例2: 基于游标定义变量
DECLARE
  CURSOR c(no_ dept.deptno%TYPE) 
         IS SELECT * FROM dept where dept.deptno >= no_;
  v_dept c%ROWTYPE;
BEGIN
  OPEN c(no_ => 10); -- 该参数用于填充到Select游标绑定的查询语句中
  FETCH c INTO v_dept;
  WHILE c%FOUND LOOP
    dbms_output.put_line(v_dept.dname);
    FETCH c INTO v_dept;
  END LOOP;
  CLOSE c;
END;

案例3DECLARE
  CURSOR c IS SELECT * FROM dept;
  TYPE t_dept IS TABLE OF dept%ROWTYPE INDEX BY BINARY_INTEGER;
  v_dept t_dept;
  i INT := 0;
BEGIN
  OPEN c;
  FETCH c INTO v_dept(i);
  WHILE c%FOUND LOOP
    i := i + 1;
    FETCH c INTO v_dept(i);
  END LOOP;
  CLOSE c;
  FOR i IN v_dept.first..v_dept.last LOOP
    IF v_dept.exists(i) = TRUE THEN
       dbms_output.put_line(v_dept(i).dname);
    END IF;
  END LOOP;
END;

3.游标的for循环
PL/SQL语言提供了游标FOR循环语句,自动执行游标的OPEN、FETCH、CLOSE语句和循环语句的功能

DECLARE
  CURSOR x IS SELECT * FROM dept;
BEGIN
  FOR y IN x LOOP
    dbms_output.put_line(y.dname);
  END LOOP;
END;

4.隐式游标的用法
对于非查询语句,如修改、删除操作,ORACLE 系统会自动地为这些操作设置游标并创建其工作区,这些由系统隐含创建的游标称为隐式游标。
隐式游标的名字为SQL
对于隐式游标的操作,如定义、打开、取值及关闭操作,都由ORACLE 系统自动地完成,无需用户进行处理
用户只能通过隐式游标的相关属性,来完成相应的操作
在隐式游标的工作区中,所存放的数据是与用户自定义的显示游标无关的、最新处理的一条SQL语句所包含的数据

隐式游标的属性
在这里插入图片描述

隐式游标使用案例1:

DECLARE
    V_deptno department_id%TYPE :=&p_deptno;
BEGIN
    DELETE FROM employees WHERE department_id=v_deptno;
    IF SQL%NOTFOUND THEN
        DELETE FROM departments WHERE department_id=v_deptno;
    END IF;
END;

5.锁定游标的结果集
游标修改和删除操作是指在游标定位下,修改或删除表中指定的数据行。这时,要求游标查询语句中必须使用FOR UPDATE选项,
以便在打开游标时锁定游标结果集合在表中对应数据行的所有列和部分列。

案例:从EMPLOYEES表中查询某部门的员工情况,将其工资少于1000的调整为1000

DECLARE
  CURSOR c IS SELECT * FROM emp FOR UPDATE;
BEGIN
  FOR x IN c LOOP
    IF x.sal < 1000 THEN
      UPDATE emp SET sal = 1000 WHERE CURRENT OF c;
    END IF;
  END LOOP;
END;

四、函数

Oracle中的函数一般都是对数据的简单处理,可以方便复用。
说明:以下示例中的dual是一个伪表,用于返回一个结果集的临时视图

日期函数

获取系统日期
sysdate

获取系统时间
current_timestamp
 
格式化日期
to_char(sysdate,'yyyy-mm-dd hh24:mi:ss')

将字符串转换成日期
to_date('2004-05-07 13:23:44','yyyy-mm-dd hh24:mi:ss')

添加月份
select add_months(sysdate, 2) from dual;

返回日期中指定月的最后一天
select last_day(sysdate) from dual

计算两个日期之前相差多少个月
select months_between(sysdate, add_months(sysdate, 4)) from dual

返回下个星期2是哪一天
# 星期日 = 1  星期一 = 2  星期二 = 3  星期三 = 4  星期四 = 5  星期五 = 6  星期六 = 
# 7
SELECT NEXT_DAY(SYSDATE, 2) FROM DUAL;

用于返回日期/时间的单独部分,比如年、月、日、小时、分钟等等
# year、month、day、hour、minute、second
select extract(year from sysdate) from dual;

数字函数

返回x的绝对值
abs(x)

返回大于等于x的最小整数值
ceil(x) 

返回小于等于x的最大整数值 
floor(x) 

返回x的y次幂
power(x,y) 

返回x除以y的余数 
mod(x,y) 

返回四舍五入后的值
round(x[,y]) 

返回x的平方根 
sqrt(x) 

返回x按精度y截取后的值,y为正,表示保留的小数位数,y为负,小数点左边y位变成0,y为0或不写取整
trunc(x[,y]) 

字符函数

将数字转换成字符
chr(x)

将字符转换成数字
ascii

连接字符串
concat

删除左边空格
ltrim

删除右边空格
rtrim

删除两边空格
trim

转换成大写
upper

转换成小写
lower

替换
replace(string,search_str[,replace_str])

替换,和replace相同,但比replace强大。如select 
translate(string,from_str,to_str)
translate('abcbbaadef','bad','#@') from dual (b将被#替代,a将被@替代,d对应的值是空值,将被移走)

填充/截取到x个长度,不足的话右边用指定字符填充
rpad(string1,x[,string2])

填充/截取到x个长度,不足的话左边用指定字符填充
lpad(string1,x[,string2])

截取子串
substr(string,a[,b])

求字符串的长度
length

转换函数
这里主要讲decode()函数
decode函数格式为decode(condition,val1,result1,val2,result2…)
其中condition为判断值(可以为一个值,也可以是一个表达式),val1与val2为比较值,当有一个val值与判断值相等时,此方法就会返回这个val值后的result值。返回的result值也可以是一个表示式或是一个查询语句。
下面案例列举出来了它的用法:

-- 当查询的d_id值为1是方法的最终结果为'一号',为2时返回值为'二号'。
select decode(d_id,
1,'一号',
2,'二号',
3,'三号') from dept;

-- 嵌套查询的用法
select decode(d_id,
1,(select d_name from dept where d_id = 1),
2,(select d_name from dept where d_id = 2),
3,(select d_name from dept where d_id = 3)
) from dept;

空值函数
用于补充空值

-- expr1为NULL,返回expr2;不为NULL,返回expr1。注意两者的类型要一致
select NVL(d_name,1) from dept;

-- expr1不为NULL,返回expr2;为NULL,返回expr3。expr2和expr3类型不同的话,expr3会转换为expr2的类型
NVL2(expr1, expr2, expr3)

-- expr1和expr2相等返回NULL,不等则返回expr1
NULLIF (expr1, expr2) 

五、索引与序列

索引

索引的优点:
索引是关系数据库中用于存放每一条记录的一种对象,主要目的是加快数据的读取速度和完整性检查。通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。 通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。
索引的不足:
1、创建索引和维护索引要耗费时间,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护。
2、索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。

创建和删除索引的方式

# 创建索引
CREATE [unique] INDEX [user.]indexON [user.]table (column [ASC | DESC] [,column[ASC | DESC] ] ... )
# 删除索引
DROP INDEX [schema.]indexname

序列

序列是为数据插入时提供一个自动增长的数值,它是一个数据库对象,专门用于生产数字,该数字通常为记录的id提供一个唯一的标识值

创建和删除序列

-- 创建序列
create sequence 序列名 
increment by n
start with x
[(maxvalue/minvalue y)|nomaxvalue]
[cycle|nocycle]
[cache n|nocache];

--删除序列
drop sequence 序列名

六、Oracle 高级对象(存储过程、异常处理、自定义函数、包、视图)

存储过程
存储过程是一个可以用编程的方式来操作SQL的集合,其实就是一个带名字的pl/sql块
优点:
1、执行效率高。因为存储过程是预编译的,即创建时编译,而SQL语句是执行一次,编译一次。
2、调用存储过程可以大大减少同数据库的交互次数。
3、降低网络通信量。因为存储过程执行的时候,只需要call存储过程名,不需要传递大量的SQl语句。
4、有利于复用
缺点:
1、移植性非常差,如果在oracle上写的存储过程,移植到mysql需要修改。
2、代码可读性差,实现一个简单的逻辑,代码会非常长。

如何定义存储过程
语法:

CREATE [OR REPLACE] PROCEDURE 
   <procedure name> [(<parameter list>)]
IS|AS 
   <local variable declaration>
BEGIN
   <executable statements>
[EXCEPTION
   <exception handlers>]
END;

示例:

-- 创建一个存储过程
CREATE OR REPLACE PROCEDURE simple(a INT DEFAULT 200 , b INT) IS
  c INT;
BEGIN
  c := a + b;
  dbms_output.put_line(c);
END;

-- 执行存储过程
set serveroutput on;
BEGIN
  simple(b => 200);
END;

存储过程的参数类型
1.IN
表示输入参数,是参数的默认模式。
2.OUT
表示返回值参数,类型可以使用任意Oracle中的合法类型。模式定义的参数只能在过程体内部赋值,表示该参数可以将某个值传递回调用他的过程
3.IN OUT
表示该参数可以向该过程中传递值,也可以将某个值传出去

示例:

# 创建存储过程
CREATE OR REPLACE PROCEDURE simp(
       s_no in int,
       s_name out varchar,
       s_part in out varchar
       ) AS
BEGIN
  dbms_output.put_line('程序内可用:'||s_no);
  dbms_output.put_line('程序内不可用:'||s_name);
  dbms_output.put_line('程序内可用:'||s_part);
  s_name := '小明';
  s_part := '市场部';
end;

# 测试使用
set serveroutput on;
declare
  s1 varchar2(10):='初始值';
  s2 varchar2(10):='初始值';
begin
  simp(s_no => 1,s_name => s1,s_part => s2);
  dbms_output.put_line('值被返回了:'||s1);
  dbms_output.put_line('值被返回了:'||s2);
end;

测试结果:
在这里插入图片描述

删除存储过程

drop procedure 过程名

存储过程使用注意事项!!!
1.数据量大的时候(10万+),一定要做压力测试,有些存储过程在大数据量的情况下才会出现问题。
2.如果插入或者更新的次数比较多,为了提高效率,可以执行一万次,再commit一次。
3.如果先插入记录,没有commit,再对这条记录进行更新,会引起死锁。如果先后对同一笔记录进行更新,又没有commit,也会引起死锁。因为后一条语句会等待前一条语句提交。如果出现这种情况,则需要一条条commit。
4.不要忘记在存储过程里写commit。

异常处理
在存储过程中,要处理异常。异常的类型包括预定义异常,非预定义异常和自定义异常

预定义异常说明
access_into_null试图给一个没有初始化的对象赋值
case_not_found在Case语句中没有WHEN子句被选择,并且没有ELSE子句
invalid_number试图将一个非有效的字符串转换成数字
loggin_denied使用无效的用户名和口令登录oracle
no_data_found查询语句无返回数据,或者引用了一个被删除的元素,或者引用了一个没有被初始化的元素
timeout_on_resourceoracle在等待资源时发生超时的现象

预定义异常处理案例
预定义即系统已经定义好的异常,我们可以直接使用它。

REATE OR REPLACE PROCEDURE simple IS
       v INT;
BEGIN
  v := 1 / 0;
EXCEPTION
  WHEN ZERO_DIVIDE THEN
    dbms_output.put_line('除数不能为0');
END;

BEGIN
  simple;
END;

非预定义异常处理案例
非预定义异常是Oracle没有提供的常量,由我们自定义,然后由Oracle自动引发。

CREATE OR REPLACE PROCEDURE ins IS
  myerror EXCEPTION;
  PRAGMA EXCEPTION_INIT(myerror, -1);
BEGIN
  INSERT INTO dept VALUES(10, 'aaa', 'aa');
EXCEPTION
  WHEN myerror THEN
    dbms_output.put_line('主键重复');
END;

BEGIN
  ins;
END;

自定义异常
自定义异常也是需要我们自己定义,与预定义异常不同的是自定义异常需要使用Raise关键字显示的引发异常。

DECLARE
     temp_ex exception;
     t_num integer;
BEGIN
    select count(id) into t_num from temp_table where   id='1031';
    IF t_num>=1 THEN
         RAISE temp_ex;
    END IF;
    DBMS_OUTPUT.PUT_LINE('该用户不存在');
    EXCEPTION
        WHEN temp_ex THEN
              DBMS_OUTPUT.PUT_LINE ('该用户已存在');
END;

自定义函数
函数的结构
(1)声明部分:包括类型、变量、游标
(2)执行部分:完成功能而编写的SQL语句或则是PL/SQL代码块
(3)异常处理部分
语法:

CREATE [ OR REPLACE] FUNCTION function_name
[ ( parameter1 [ { IN | OUT | IN OUT} param1_type
parameter2 [ { IN | OUT | IN OUT} param2_type
……
parameterN [ { IN | OUT | IN OUT} paramN_type]]
RETURN returntype { IS | AS }
function _body;

案例

create or replace function maxvalue0(a number,b number)
return number  --设置方法返回类型
as
  c number; --声明变量,函数中不需要declare语句
begin --执行程序
  if(a > b) then
    c:=a;
  else
    c:=b;
  end if;
  return c; --返回值
end;

过程与函数的比较

过程函数
标识符PROCEDUREFUNCTION
返回值必须使用变量形参用函数名直接返回
赋值不能赋值并定义类型可以定义类型,并直接赋值
调用方式独立的过程调用句以表达式调用
目的完成一系列的数据处理获得函数返回值


包用于管理过程与函数

包规范
用于定义常量、变量、游标、过程和函数等用户与程序的接口
可以在包内引用,也可以被外部程序调用

包主体
是包规范的实现,包括变量、游标、过程和函数等
包体内的内容不能被外部应用程序调用

包的定义与调用

-- 包的定义
CREATE OR REPLACE PACKAGE BODY mypck
IS
  FUNCTION add_(a INT, b INT) RETURN INT IS
  BEGIN
    RETURN a + b;
  END;
  PROCEDURE dept_count(c OUT INT) IS
  BEGIN
    SELECT COUNT(*) INTO c FROM dept;
  END;
  PROCEDURE print_emp(ci OUT c) IS
  BEGIN
    OPEN ci FOR SELECT ename FROM emp; --返回游标
  END;
END;

-- 调用包
DECLARE
  c INT;
  ci mypck.c;
  n emp.ename%TYPE;
BEGIN
  c := mypck.add_(10, 90);
  dbms_output.put_line(c);
  mypck.dept_count(c);
  dbms_output.put_line(c);
  mypck.print_emp(ci);
  FETCH ci INTO n;
  WHILE(ci%FOUND) LOOP
    dbms_output.put_line(n);
    FETCH ci INTO n;
  END LOOP;
  CLOSE ci;
END;

视图
视图的特点
(1)视图一个数据库中虚拟的表
(2)经过查询操作形成的结果
(3)具有普通表的结构
(4)不能实现数据的存储
(5)对视图的修改将会影响实际的数据表

创建和销毁视图

-- 创建视图
create [or replace] view view_name as
<select statement>
-- 销毁视图
drop view view_name
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值