Oracle基础知识

--------------------------------Oracle 基础知识 -----------------------------

1.      超级用户

用户名      默认口令

sys        change_on_install

system    manager

scott      tiger

2.      select * from tab 查询当前的登录用户所拥有的表

3.      数据类型

(1)  数值类型

number(4)  表示 -9999 9999

number(7 2   表示 -99999.99 99999.99

number  表示 10^-38 10^38(10 的负 38 次幂到正 38 次幂 )

(2)  字符类型

varchar2 变长   varchar2(N) N 的最大取值为 4000 字节

char 定长 char(N) N 的最大取值为 2000 字节

例如:

张三 字符分别存入 varchar2(20) char(20) 中,那么

varchar2(20) 中实际的就是 4 个字节,

char(20) 中是 20 个字节, 张三 4 个字节,剩下 16 个字节是空格

(3)  日期类型

Date  7 个字节   年月日 时分秒

(4)  大对象类型

字符类型 clob  可存放 4G 字符内容

二进制类型 blob  超过 4G ,可存放图片,音乐等

4.      Oracle 与其他数据库的区别

(1)  sqlserver: 分成若干的数据库,在不同的数据库中建立数据表

(2)  oracle 是分用户操作,每一个用户就是一个数据库

5.      Oracle 系统函数

系统函数分为:单行函数和分组函数

单行函数:

(1)  sysdate 日期函数

查看当前系统日期

select sysdate from dual;

查看当前系统日期时间

select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;

dual 是哑元表

两个日期相减 = 两个日期间隔的天数

计算两个日期间隔的月份

select month_bewteen(sysdate,hiredate) from emp;

      236 月以后是哪个日期

           select add_months(sysdate,236) from dual;

      236 月以前是哪个日期

           select add_months(sysdate,-236) from dual;

      当前月的最后一天

           select last_day(sysdate) from dual;

 

      当前月的倒数第二天

           select last_day(sysdate)-1 from dual;

      当前时间开始的下一个星期一的日期 ( 中国方式 )

           select next_day(sysdate,' 星期一 ') from dual;

      scott emp 表中查哪个人的日期是注册时月份的倒数第三天

select * from emp where HIREDATE in(select last_day(HIREDATE)-2 from dual);

      今天是一周中的第多少天

           select to_char(sysdate,'D') from dual

      今天是一年中的第多少天

           select to_char(sysdate,'DDD') from dual;

      向数据库中插入日期格式的数据,以 Scott emp 表为例

            insert into emp values

(7035,'Shiki','CLERK',1000,to_date('1988-12-27','yyyy-mm-dd'),

1500,0,10);

      设置系统的日期插入格式为日月年

           alter session set nls_date_format='dd-mm-yyyy';

(2)  数值函数

字符串转换数值

select to_number('56')+1 from dual;

      字符串连接

           select to_char(15)||'123' from dual;

      数值转换日期

           select to_date(to_char(19801215),'yyyy-mm-dd') from dual;

      大于 n 的最小整数

           select ceil(5.6) from dual;   返回值为 6

      小于 n 的最大整数

           select floor(5.6) from dual;   返回值为 5

      求余数

           select mod(3,2) from dual;   返回值为 1

      四舍五入 ( 可以和日期连用 )

           select round(4.5) from dual;

           select round(4.567,2) from dual;   小数点后保留两位小数

      截断 ( 可以和日期连用 )

           select trunc(4.9) from dual;   返回值为 4

            select to_char(trunc(sysdate),'hh24:mi:ss') from dual;

(3)  字符函数

连接 ||

      select 'hello' || 'world' from dual;

select to_char(sysdate,'yyyy')||' '||to_char(sysdate,'mm')||' '||to_char(sysdate,'dd')||' ' from dual;  

返回值为 2010 05 14

 

      首字母大写

           select initcap(ename) from emp;

全部字母大写

      select upper(ename) from emp;

全部字母小写

           select lower(ename) from emp;

      左填充 / 右填充   lpad/rpad

           select lpad(ename,10,' ') from emp; 

ename 这个字段设置为 10 个字节长度,多余的位置用空格在左侧填充

           select rpad(ename,10,' ') from emp;

ename 这个字段设置为 10 个字节长度,多余的位置用空格在右侧填充

      / / 全去空格   ltrim/rtrim/alltrim

            select ltrim(ename) from emp;

      替换,将大写 S 替换为小写 s

           select ename,replace(ename,'S','s') from emp;

      转换 translate

           将大写 S 转换为 $ 符号

           select ename,translate(ename,'S','$') from emp;

      ASCII   ASCII 码可以和 char 值之间相互转换

           ASCII—ascii    char---chr

           select ascii('a'),chr(97) from dual;

      截取 substr

           截取 ename ,从第一位开始截,截取 3

           select ename,substr(ename,1,3) from emp;

      测试长度 length

      查询字符次数  

           查询 ename 中出现过字符 S 的次数

select instr(ename,'S') from emp;

(4)  混合函数

求最大值 greatest

           select greatest(100,15,24,56,90) from dual;

      求最小值 least

           select least(100,15,24,56,90) from dual;

      空值转换 nvl

           select nvl(sal,0)+nvl(comm,0) from emp;

           如果有空值,用 0 代替,

如果这样写 select sal+comm from emp; 值为空的数据将会被屏蔽,不会参与加运算

      结构分支 if—else ,可用 decode 函数代替

select sal,decode(sal,800,' 低工资 ',3000,' 正常 ',5000,' 高工资 ',' 不判断 ') from emp;

           按照顺序书写

           800= 低工资, 3000= 正常, 5000= 高工资,否则剩下的都 = 不判断

 

      判断正负

           select sign(1) from dual;       如果判断 0 ,结果还为 0

      decode sign 可以联合使用

select sal,decode(sign(sal-1000),1,' 低工资 ',2,' 高工 ',' 正常 ') from emp;

 

分组函数:

Group by

Sum

Avg

Count

 

第一列值的个数

select count(1) from emp;

emp 表中不同的工作的个数

select count(distinct upper(job)) from emp;

 

distinct 只能去除重复行,不能去除重复列

 

分组函数是对分组之后的内容进行操作

 

平均工资大于 1300

      select job,avg(sal) from emp group by job having avg(sal)>1300;

每个部门里每种工作工资最高和最低的

      select deptno,max(sal),min(sal) from emp group by deptno,job;

 

 

------------------------------ 约束的应用 ------------------------------

1.      约束是应用在数据表的创建过程中:

主键约束,非空约束,唯一性的约束,外键约束,检查约束

create table cla(

      Id number(2) primary key,

      Cname varchar2(20) not null

)

create table stu(

      xh number(4) primary key,

      xm varchar2(20) not null,

age number(2) check (age between 10 and 90),

–- 检查的约束,检查这个字段输入的内容

birthday date,

code number(18) unique, -- 唯一性约束

sex char(2) check(sex in(‘ ’,’ ’)), -- 检查约束

sal number(7,2) check(sal between 500 and 1000); -- 检查约束

classid number(2) references cla(id)

–- 外键约束,括号中要引用的一定是主表中的主键或者是唯一键

)

-- 问题:创建约束的时候,没有指定约束的名字,这时系统会自动创建,那么以后修改约束的时候就会很有问题,管理起来十分麻烦,不推荐使用这种直接创建约束的方式

解决方法:先创建表,然后在添加约束

 

从数据字典中查看默认约束

select * from user_constraints; 当前用户下创建的所有约束

查看 stu 表中的约束

      select * from user_constraints where table_name='stu';

2.      添加约束

添加主键约束

      alter table stu add constraint pk_stu primary key(xh);

添加外键

      alter table stu add constraint fk_stu foreign key(classid) references cla(id);

添加非空约束

      alter table stu modify( xm not null);

添加检查约束

      alter table stu add constraint ck_sal check(sal between 500 and 1000);

      alter table stu add check(sex in(‘ ’,’ ’)); -- 这个表示还是没有对约束起名字

添加唯一性约束

      alter table stu add constraint uq_sfz unqiue(code);

3.      删除约束

Alter table 表名 drop constraint 约束名 ;

 

 

------------------------------ 关联查询 ------------------------------

当出现多个数据表时,彼此之间存在主外键的关系

关联查询, sql 功能的实现,性能要高,连接的条件的个数 = 表的个数 -1

只要参加连接的字段存放的数据代表的含义相同,就可以连接在一起,不一定是主外键的关系

1.      内连接 ( 内查询 ) :多表查询,完全匹配的记录的查询操作

Select dname,ename from emp, dept where dept.deptn=emp.deptno where deptno=10;

将两张表匹配成一张大表,效率最低

2.      标准的 sql 查询   连接的条件要使用 on 表示

Select dname,ename from emp inner join dept on dept.deptn=emp.deptno where deptno=10;

3.      外连接的查询 ( 使用的最频繁 ) :多表中的部分匹配的记录的查询

      左外连接,右外连接,全外连接

可以用 + 号和 outer join 来实现外连接

select dept.deptno,dname,ename from emp,dept where emp.deptno(+)=dept.deptno;

+ 号的作用是选择哪个部分来作为条件匹配,以 + 号对面的记录作为匹配条件来显示

+ 号在右边表示左外连接, + 号在左边表示右外连接

左外连接

      Select dept.deptno,dname,ename from dept left outer join emp on dept.deptno=emp.deptno;

右外连接

      Select dept.deptno,dname,ename from dept right outer join emp on dept.deptno=emp.deptno;

全外连接

      Select dept.deptno,dname,ename from dept full outer join emp on dept.deptno=emp.deptno;

4.      自连接

查询每个员工的姓名以及上级的名称

Select a.ename,b.ename from emp a,emp b where a.ename=b.mgr;

5.      子查询

查询工资比 smith 高的

select ename,sal from emp where sal>(select sal from emp where ename=upper('smith'));

查询至少有一个员工的部门

方法 1 ( 分组 )

select deptno from emp group by deptno having count(ename)>=1;

方法 2 ( 自查询 )

select deptno from dept where(select count(*) from emp where emp.deptno=dept.deptno)>=1;

显示部门里边的详细信息,以及它的人数

select a.*, (select count(*) from emp where deptno=a.deptno) as 人数 from dept a;

显示每个部门工资最高的员工的姓名

方法 1 ( 分组 )

select deptno,ename,sal from emp where (deptno,sal) in (select deptno,max(sal) from emp group by deptno);

方法 2 ( 自查询 )

select deptno,ename,sal from emp a where (select count(*) from emp b where a.sal>b.sal and deptno=a.deptno)=0;

      找出每个部门工资最高的员工的姓名的前两个人

方法 1 ( 自查询 )

select deptno,ename,sal from emp a where (select count(*) from emp b where a.sal>b.sal and deptno=a.deptno)<2 order by deptno;

方法 2 ( 伪列 rownum)

select ename,sal from (select * from emp order by sal desc) where rownum<=2;

 

 

---------------------------3 种数据库的分页方式 -------------------------

1.      Oracle 的分页操作

对于所有的 Oracle 的数据表,都包含伪列 rowid rownum

rowid:2 进制数据,反映的是当前的记录,在硬盘的物理位置 ( 最底层的索引列 ) ,物理位置

rownum: 逻辑的次序序列,逻辑位置

当修改表的记录时,不会修改记录的物理位置,只更改逻辑位置

Oracle 的分页操作通过伪列 rownum 来实现

select * from emp where rownum<=3 ;

select * from (select e.*,rownum as num from emp e) where num between 6 and 10;

(select e.*,rownum as num from emp e) 将这个看作是一个视图来操作

分页公式:

6 的位置:开始查询的起始记录次序 ( 当前的页数 -1)× 每页的显示的个数 +1

10 的位置:终止的次序编号,当前的页数 × 每页的个数

以上的写法只能应用于数量较小的表,

select * from (select e.*,rownum as num from emp e where rownum<16) where num between 10 and 16;

 

select * from

(select e.* from

(select e.*,rownum as num from emp e where rownum<16) e

where rownum>=10)

以上的写法适用于海量数据的分块查询方式的书写

2.      MySQL 的分页

Select * from users limit n,m;

N: 起始的记录次序 ( 当前页数 -1)×m

M :查询几个

3.      SQLServer 的分页

Top 指令:

            Select top 5 * from pubs;

Top 指令 +not in( 一定有主键或唯一键的参与 )

Select top m * from pubs where id not in(select top n id from pubs)

M: 表示每页显示的个数

N:( 当前页数 -1)×m

Id: 表示主键或唯一键

 

 

---------------------------SQL 语句的分类 -------------------------

1.      DDL— 数据定义语言

包括 create,drop,alter,truncate

Drop table 表名   ----- 数据和表结构同时删除,不可恢复

truncate table 表名 ----- 截断表 ( 删除表中的数据,保留结构,不写日志文件 )

delete from 表名 -----DML 语言,数据删除,结构保留,可以恢复

2.      DML— 数据操作语言,操作实际是在内存中完成,必须执行 commit ,才能影响数据库

包括 select,insert,update,delete

3.      TCL— 事务控制语言

包括 commit,rollback,savepoint

Oracle 中所有的事务都是隐性的 ----- 不会自动提交

set autocommit on/off  打开或关闭自动提交

DDL 指令全部都是自动提交的

4.      DCL----- 数据控制语言

grant— 分配权限,

revoke— 回收权限

 

 

-----------------------------Oracle 用户管理 ----------------------------

1.      创建用户,分配权限

只有超级用户 system 才有权进行创建的操作

切换到 system 用户

connect sys / admin as sysdba

创建用户 , 但用户还未被激活

      Create user Shiki identified by t123;

      用户名: Shiki      密码: t123

分配权限

      grant connect,resource to Shiki;

connect :登录权限

      resource :可以使用资源空间的权限

给予 DBA 权限

      grant dba to Shiki;

分配操作

      grant select on emp to Shiki;

      grant delete on emp to Shiki;

      如果不分配操作权限,那么就是一个傀儡用户,不能执行任何操作,即使给予了 DBA

           Grant all on emp to Shiki;  给予所有操作权限

删除用户

      drop user Shiki;

级联分配

      Grant all on Scott.emp to Shiki with grant option;

回收权限

      Revoke all on Scott.emp from Shiki;

2.      查看用户

select * from all_users;   查看 Oracle 中的所有用户

3.      修改用户

修改用户的密码

Alter user Shiki identified by aaa;

4.      解锁

Alter user scott account unlock;

5.      切换用户, connect

用户名 / 密码 as 权限

  connect sys / admin as sysdba

6.      connect scott/tiger as normol

7.      显示当前用户   show user;

 

 

------------------------------------- 技巧型 SQL 语句 --------------------------------------

1.      创建一个表的备份

Create table myemp as select * from emp;

2.      备份一张表的结构

Create table myemp as select * from emp where 1=2;

只要 where 条件为假就可以

3.      Insert 多条数据

Insert into myemp select * from emp where deptno=30;

      定义变量

Insert into myemp(empno,ename) values(&eno,’&ename’) 

一般出现在后台的测试过程中

4.      集合运算符的使用

A(1,2,3,4,5,6)     B(1,2,3)   两张数据表

A 交集 B  intersect  123

A 并集

union -123456

union all -123123456

A 差集 B minus 

a-b 456

            b-a 空集

集合用 select 语言来查询

Select num from A intersect select num from B

 

select distinct xm from grade a

where

not exists(

(select subject from grade where xm='tom')

      minus 

(select subject from grade where xm=a.xm)

)

and a.xm<>'tom'

 

 

----------------------------------------- 数据对象 -----------------------------------------

1.      序列 ( 自动的增长列 )

sequence: 开始是任意的,可以手动指定增长的长度,可以循环,可以包含负值和某一个数据表的列联合使用,属于 DDL 定义语言

创建一个表

create table employee(

bh number(4) primary key

)

开始创建序列

Create sequence seq1

Start with 100 – 100 开始,自增为 1

使用序列

序列中包含两个属性,

当前值: currval

下一个值: nextval

Select seq1.nextval from dual

Insert into employee values(seq1.currval)

每调用一次序列的属性 nextval ,其值会自动 +1

 

复杂的序列:

Create sequence seq

Start with 1000   -- 起始 1000

Increment by 3  -- 步长为 3

Maxvalue 9999   -- 最大值 9999

Minvalue 900 -- 最小值

Cycle(nocycle)    表示循环 / 不循环

order-- 按次序产生序列值

如果进行循环,将按照步长取值,且不会取最大值和最小值之间的重复值,所有的值只取一次,直到所有的值被循环一次为止

 

2.      视图: sql 的查询的结果,简化 sql 语句的使用

视图和物理表的关系:视图不是表,只是存放一个 sql 语句 ( 虚表 )

创建视图:

Create or replace view v_emp

As

Select * from emp wwhere deptno=30;

如何查询当前的用户拥有的视图

Select * from tab where tabtype=’view’;

视图分类:简单的视图 复杂视图

视图中的数据和表中的数据是同步的,表或视图发生变化时,都会相应的发生改变

(1)  简单视图 -- 创建视图的 sql 语句中,如果没有使用分组函数,就称为简单视图,与表是一种一一映射的关系,视图中的一条记录对应于表中的一条记录,这样我们可以通过修改视图实现表的修改操作,简化操作的方式

一般情况下,不需要让视图具有修改表的权限,一般是只读的

设置视图的权限:

      只读的权限: with read only

      Create or replace view v_emp

As

Select * from emp wwhere deptno=30 with read only;

修改的权限,检查视图:通过视图进行修改 with check option

当进行 insert update 操作时,会对数据进行检查,

检查创建视图的 where 语句的限制

(2)  复杂视图 不能通过视图修改表的视图 ()

 

3.      索引 ( 加快 select 语句的执行,自动执行的 )

(1)  默认索引,添加约束的时候,索引自动添加

Primary key

Unique

索引都是建立在列上,牺牲空间换取效率,一个索引相当于书的目录

(2)  普通索引 ( 配合 where 的条件 )

Create index ind_emp_ename on emp(ename,job)— 属于逻辑的索引

   Rowid 是查询速度最快的索引

缺点:,用空间换速度,索引会使表的增删改的操作速度降低 ( 索引是自动维护的 )

(3)  唯一性索引:引用索引的字段只能出现一次

Create unique index idx_sal on emp(sal)

(4)  位图索引:针对数据表某个列的取值在一个很小的范围之内

Create bitmap index ind_sex on emp(sex)

   Select * from emp where sex=’ ’; 查询时会触发这个索引

(5)  簇索引:用于关联的查询,检查物理位置靠近的存放

(6)  反向间的索引:正常的序列是 ABC ,建立索引后按照 CBA 反序查

(7)  函数索引

 

Sql 语句如何使用索引:

Select * from emp;  这种查询方式称为全表扫描,无法自动触发索引

要使用索引,则 select 语句中必须存在 where 字句

例如:

Emp 表中查询 1960.5-2000.5 这个期间中的员工

Create index ind_date on emp(hiredate)

查询语句如何写?这里要有技巧

也许大多数人都会这样

      Select * from emp where to_char(hiredate,’yyyymm’)>=’196005’ and

to_char(hiredate,’yyyymm’)<=’200005’

虽然这句 sql 语句包含了 where 子句,但是没用到索引,此时索引是不产生效果的

Where 字句中必须出现索引字段 ( 字段一定直接连接比较运算符 ) ,此时索引才会执行

Select * from emp where hiredate>=to_date(‘196005’,’yyyymm’) and hiredate<=to_date(‘200005’,’yyyymm’)

索引字段不能参与运算

例如: hiredate+2>=to_date(‘196005’,’yyyymm’)

相反,可以这样写: hiredate>=to_date(‘196005’,’yyyymm’)-2

 

4.      同义词

数据库对象的别名

Create synnonym 名字 for scott.emp — 私有同义词 , 哪个用户创建的,这个同义词只属于该用户

Create public synonym 名字 for scott.emp – 公有同义词 emp 表公开了,其他用户都可以访问

5.      数据对象的删除

Drop 数据对象类型 名字

 

 

----------------------------------------- 数据字典 ----------------------------------------

数据字典是 Oracle 当中的系统信息库,配置信息和数据信息都在里边,所有者是 sys

数据字典的权限分为,这三个是数据字典的前缀

      user_ 

      all_

      dba_

 

后缀分为:

Tables

Object

Procdurce

Function

Package

 

常用的数据字典的查询命令

一个用户有哪些表

      Select object_name from user_objects where object_type=’TABLE’;

用户可以访问的数据表

      Select table_name from all_talbes where owner=’’;

系统中有哪些用户

      Select * from dba_users;

 

 

--------------------------------------PL/SQL 的编程 --------------------------------------

PL :过程化的语言,包括 if ,循环等

SQL :结构化查询,

解决的问题:一条 SQL 语句不能完成的操作,模块化功能

1.      PL/SQL 块的格式 ( 匿名的 )

Declare

-- 定义变量 ( 先定义,后使用 )

Begin

-- 业务操作,执行语句 (DML) ,可以包含事务性控制 (TCL) 提交,回滚等,但不包括 select

--DDL DCL 是不能直接写在 PL/SQL 块中

Exception

-- 异常处理

End

 

定义变量

-- 变量名 变量的类型

aa number(2); --30 个字符之内,第一个字母不能是数字

设定初值

      bb number(5) default 1000;

      cc number(5,2) :=12.45( 变量类型与:之间要有空格 )

      dd varchar2(20) :=’Hello’;

      birthday date;

      islogin Boolean :=false;

      pi constant number :=3.14;

利用数据库的属性定义

      eno emp.empno%type;

      -- 行变量的定义

      erow emp%rowtype;

赋值

      Date:=’01-4 -05’;

      -- 通过 select 语句

      Select sysdate into birthday from dual;  --PL/SQL 块中如果出现 select ,则一定是 select…into 的格式,不可能出现 select * 这种格式

           Select to_char(sysdate,’yyyymmdd’) into dd from dual;

           -- 通过键盘的输入

           Bb:=&number;

           Ename:=’&name’;

           Select sal,ename into bb,ename from emp where empno=7369;  -- 赋值时一定要保证唯一性

      打印输出

      Dbms_output.put_line(‘bb=’||bb);

      要想使用 pl/sql ,一定要添加显示控制

      Set serveroutput on;

输入一个员工号,得到该员工的工资的总和 sal+comm.

      set serveroutput on;

declare

  sc_sum number(5);

  s emp.sal%type;

  c emp.comm%type;

  e emp.empno%type;

begin

  e:=&number;

  select nvl(sal,0),nvl(comm,0) into s,c from emp where empno = e;

  sc_sum := s+c;

  DBMS_output.put_line(' 工资总和 ='||sc_sum);

end;

输入一个部门号,得到部门的人数,最高工资,最低工资,平均工资

set serveroutput on;

declare

  d emp.deptno%type;

  c number(5);

  s_max emp.sal%type;

  s_min emp.sal%type;

  s_avg emp.sal%type;

begin

  d := &number;

  select count(empno),max(sal),min(sal),avg(sal) into c,s_max,s_min,s_avg from emp where deptno=d;

  DBMS_output.put_line(' 部门人数 ='||c||', 最高工资 '||s_max||', 最低工资 '||s_min||', 平均工资 '||s_avg);

end;

 

2.      循环

Declare

I number(2);

Begin

 

(1)  Loop 循环    loop(do_while)

i := 0;

Loop

      Exit when i=10;

      DBMS_output.put_line(i);

      i =i+1;

end loop;

(2)  While 循环

i := 6;

while(i<10 and i>5) loop

      DBMS_output.put_line(i);

      i:=i+1;

End loop;

(3)  for 循环

for I in 1..10 loop

      DBMS_output.put_line(i);

End loop;

 

3.      if…else 语句

if 条件 then

  sleif then

      elsif then

else

end if

 

根据员工编号涨工资,如果 deptno=10 10% =20 20% =10 30%

涨工资后达到了 >5000 ,按照 5000 计算

declare

  eno number ( 5 );

  dno emp.deptno% type ;

  v_sal emp.sal% type ;

begin

  -- 输入员工号

  eno:=& number ;

  select deptno,sal into dno,v_sal from emmp where empno=eno;

  if dno= 10 then

     if v_sal* 1.1 > 5000 then

        update emp set sal= 5000 where empno=eno;

     else

        update emp set salsal* 1.1 where empno=eno

     end if ;

  elsif dno= 20 then

     if v_sal* 1.1 > 5000 then

  

     else

  

     end if ;

  elsif dno= 30 then

     if v_sal* 1.1 > 5000 then

  

     else

  

     end if ;

  else

     null ; -- 处理 dno=40 的情况

  end if ;

end ;

 

 

使用函数代替 if-else 语句

Update emp set sal=least(5000,sal+sal*deptno/100) here empno=eno;

 

 

4.      DDL DCL

Create table test(i number)

Grant select on emp to mike;

例如这些语句不能直接写在 begin end

只能采用间接的书写

S1 varchar2(100);

S1:=’ Create table test(i number)’;

-- 将要执行的语句写在一个字符变量中

Execute immediate s1;-- 执行字符变量的内容

接收一个员工号如果该员工职位是 manager ,并且在 dallas 工作那么就给他薪金加 15% ,如果该员工职位是 clerk ,并且在 new York 工作那么就给他薪金扣除 5% ,其他情况不做处理

 

declare

 

  eno number ( 4 );

    v_job emp.job% type ;

    v_loc dept.loc% type ;

 

begin

    eno:=&empno;

    select job,loc into v_job,v_loc from emp,dept where emp.deptno=dept.deptno and empno=eno;

    dbms_output.put_line( ' 工作 ' ||v_job|| 检验员 ' ||v_loc);

   

    if (v_job=upper( 'manager' ) and v_loc=upper( 'dallas' )) then

       dbms_output.put_line( ' 涨工资 15%' );

    elsif (v_job=upper( 'clerk' ) and v_loc=upper( 'new york' )) then

       dbms_output.put_line( ' 降工资 5%' );

    else

        dbms_output.put_line( ' ' );

    end if ;            

end ;

 

5.      异常处理

(1)  运行时的异常错误

Declare

      Erow emp%rowtype;

Begin

      Select * into erow from emp where empno=7369; -- 这里有可能出错

      dbms_output.put_line( erow.ename||’  ’erow.sal );

/*

当前的 emp 表中有 7369 这条数据,如果我输入 9999 ,没有这条数据的时候就会报告相应的错误,或者是 Select * into erow from emp 这样写,就会报 没有匹配的数据,数据量大

*/

Exception then  -- 异常处理

异常的种类:

      Too_many_rows

      No_data_found

     

End

End;

 

完整的程序:

Declare

      Erow emp%rowtype;

Begin

      Select * into erow from emp where empno=7369;

      dbms_output.put_line( erow.ename||’  ’erow.sal );

Exception then 

      When No_data_found then   

           dbms_output.put_line( 没有匹配的数据 );

      When others then   

           dbms_output.put_line( 错误代码 ’||sqlcode||’, 错误描述 ’||sqlerrm );

           -- 这里显示的是系统全局信息

End

(2)  自定义的异常 实现一种人为的程序的执行的中断

Declare

      Eno number(2);

      Myexp exception;

Begin

      Eno:=&empno;

      If eno>80 then

            Raise myexp;-- 引发异常

End if;

Insert into dept values(eno,’&name’,’&loc’);

Commit;

Exception

      When myexp then – 捕获编号 >80 的错误

           dbms_output.put_line( 部门编号大于 80’ );

      When dup_val_on_index then – 唯一约束异常

           dbms_output.put_line( 部门编号已存在 );

      rollback;

      End;

 

(3)  非预定义异常:将自定义的异常和系统中的异常进行绑定

Declare

      Erow emp%rowtype;

      Myex exception;-- 创建一个自定义异常

      Pragma exception_init(myex,-1422);-- 将系统中的 1422 编号错误的异常与自定义 myex 绑定

      When myex then

           dbms_output.put_line( 查询的结果行太多 );

(4)  异常编号的范围

系统产生的异常基本在 -20000 以内

Raise_application_error(-2001,’too rows’);

(5)  主要在异常中些什么内容

Rollback;

备份方式的执行命令

写恢复类型的代码

 

 

-------------------------------------------- 游标 -------------------------------------------

游标是内存中的一块区域,存放的是 sql 语句的执行的结果 ( 暂时的,多条记录 )

游标的关键字: cursor

1.      隐式游标:单条 sql 语句产生的结果

游标的属性:

%rowcount :记录的行数 , 返回值是整数

      %found :找到的记录 (boolean)

      %notfound: 没有找到的记录 (Boolean, 没有找到记录返回值为 true)

      %isopen: 判断游标是否可用 (boolean)

2.      显式游标:应用在 select 语句,明确的访问结合集合

游标的是哟娜主要是配合循环命令, loop/for 语句

游标是单向的,只能向一个方向前进

For 循环的使用:

      Declare

           Cursor cc is select empno,ename,job,sal from emp where job=upper(‘manager’);

Ccrec cc%rowtype;

      C emp%rowType;

      Begin

           For ccrec in cc loop

dbms_output.put_line( 部门编号已存在 );

end loop;

           End;

3.      Fetch 游标指针方式

Declare

           Cursor cc is select empno,ename,job,sal from emp where job=upper(‘manager’);

Ccrec cc%rowtype;  指针方式,必须创建游标变量

Begin

      -- 遍历,打开游标

      Open cc;

      Loop;

           -- 提取游标中的一行数据

           Exit when cc%notcound;

      Dbms_ouput.put_line(ccrec.empno||’-’ccrec.ename||’-’||ccrec.jpb||’-’|| sal)

End loop;

Close cc;

End;

输入一个部门号,给这个部门的人的每个工资上调 10% ,给他的直接上级部门工资上调 5% ,如果他没有上级,直接给他的工资上调 15%

4.      参数游标:带有参数并且不确定查询结果的游标

按照部门的编号输出部门经理的名字

Declare

      Cursor c1 is select deptno from dept;-- 创建一个静态的的游标

      Cursor c2(no number,pjob varchar2) is select * from emp where deptno=no and job=upper(pjob) -- 创建动态游标

-- 这种带参的游标在声明的时候,只能声明类型,不能指定类型的长度

-- 参数只能出现在 select 语句等号的右侧

C1rec c1%rowtype; -- 创建 c1 c2 游标对应的游标变量

C2rec c2%rowtype;

Begin

      For clrec in c1 loop

           For c2rec in c2(c1rec.deptno,’manager’) loop

                 Dbms_output.put_line(c1rec.deptno||’  ’||c2rec.ename);

           End loop;

      End loop;

End;

5.      动态游标

Select 语句是一个动态的

对于游标而言,以 select 为执行的基础

Select * from emp;

游标类型是 select 查询语句产生结果的类型

Declare

-- 先定义一个类型

      Type cur is ref cursor;-- 弱类型,它可以代表所有 select 的查询的结果

      Type cur1 is ref cursor return emp%rowtype;-- 强类型

      -- 创建游标变量

      cura cur;-- 通过先前定义的 cur 类型定义该类型的变量 cura

      -- 将来的结果记录,存放在 cura

      Ccc emp%type;-- 创建配合游标使用的行变量

Begin

      Open cura for select * from emp;-- 装载游标对象 , 执行 open 操作

      /*For ccc in cura loop

           Dbms_output.put_line(c1rec.deptno||’  ’||c2rec.ename);

      End loop;*/

      -- 对于动态游标的使用,不能采用 for 语句作为遍历操作手段,所以无法执行

      -- 可以使用 loop while 等方式

      Loop

           Fetch cura into ccc;

           Exit when cura%notfound;

           Dbms_output.put_line(ccc.deptno||’  ’||ccc.ename);

End;

6.      给游标加锁

当产生一个游标的时候,遍历和修改不希望其他的用户更改表中的数据,要求你给游标进行加锁

加锁的操作是通过列来锁定行

Declare

      Cursor c is select * from emp for update of sal;-- 锁定整个结果集

Begin

      For I in c loop

           Update emp set sal=sal*1.1 where current of c;-- 通过游标修改 emp 表的记录

      End loop;

      Commit; -- 最后一定要记得解锁

      Exception

           When others then

                 Rollback;-- 解锁

      End;

 

 

---------------------------------Oracle 的数组、记录的使用 --------------------------------

1.      数组

Declare

      Type t_eno is table of number(4) index by binary_integer;

      V_eno t_eno;--t_eno 是一种数组类型,而 v_eno 就是数组变量

Begin

      V_eno(-6) :=7782;

      V_eno(0) :=7702;

      V_eno(16) :=7000;

      Dbms_output.put_line(V_eno(-6));

      Dbms_output.put_line(V_eno(0));

      Dbms_output.put_line(V_eno(16));

End;

2.      记录

Declare

Type rec is record(

      Eno number(4);

      Enm varchar2(20);

);

      R rec;-- 定义记录类型的变量

3.      将数组加载到数组中

Select empno bulk collect into v from emp;-- 将整个结果内容插入到数组中

还可以做批量更新

Forall i in 1..100

Insert into emp(empno,ename) values(r(i).eno,r(i).enm);

 

 

 

 

------------------------------Oracle 子程序 ( 命名的 pl/sql )------------------------------

1.      存储过程

格式:

Create [or replace] procedure 存储过程名 ( 参数名 in/out 数据类型 可以写多个参数 )

As   ( 相当于 declare)

      声明变量

Begin

      业务的操作

Exception

      异常的处理

End;

 

例子:

Create or replace procedure p1(pnm varchar2,psal out number)

--pnm: 调用 p1 的时候需要传入一个 varchar2 类型的参数 -

--psal: 调用 p1 的时候,设置一个 number 类型的空值,用于接受

As

      cursor ca is select * from emp where ename=pnm;

-- 生成一个查询的结果

V_ca ca%rowtype;

Begin

      For v_ca in ca loop

           Psal:=v_ca.sal;

      End loop;

Exception

      When others then

      Dbms_output.put_line(sqlerrm);

End;

 

如何调用存储过程 :

(1)  直接在命令行调用

Var aaa number;

Execute p1(‘SMITH’,:aaa);

(2)  编写 pl/sql 块的调用

Declare

      V_s number;

Begin

      p1(‘SMITH’,V_s);

      dbms_output.put_line(v_s);

end;

 

java 中,使用 Callablestatement 调用存储过程

// 输入一个部门的编号,求出该部门工资最高的员工,如果工资相同,按入场的时间的先后排序

显示的列:编号,姓名,入场时间,工资

2.      函数

函数必有返回值

格式:

Create [or replace] function 函数名 ( 参数名 参数类型 )

Return 返回类型

As

      -- 变量定义

      -- 返回变量 返回的类型

Begin

Exception

Return  变量

End;

 

例子:

Create or replace function f1(pname varchar2)

Return number

As

      V_sal number;

Begin

      Select sal into v_sal from emp where ename=pname;-- 要保证姓名是唯一的数据

Return v_sal;

End;

 

函数的调用:

(1)  Sql 下的调用:使用 dual 进行测试

Select f1('SMITH') from dual;

(2)  使用 pl/sql

Declare

      Vs number;

Begin

      Vs:=f1(‘SMITH’);

      Dbms_output.put_line(vs);

End;

 

3.      可能遇到的问题

如果需要在存储过程或函数的返回值中得到多个操作的数据 ( 多个值,多个记录 ) ,能否返回一个结果集 ( 表的结构 )

实现动态游标充当返回值:动态游标的类型如何确定

这样就要借助程序包技术来实现

 

4.      程序包的使用

是一种模块化的设计,将相同类型的函数,存储过程,类型的定义封装在一起的结构

程序包的构成:

(1)  说明部分 类似于 java 中的接口

Create [or replace] package 程序包的名字

As

      存储过程和函数的定义

      使用全局变量

      自定义的类型

     

End;

(2)  实现部门 类似于接口的实现

Create [or replace] package body 名字 ( 必须与先前定义的程序包的名字相同 )

As

      存储过程,函数的具体的实现

      使用变量,类型

End;

 

 

例子:

Create or replace package mypack as

      -- 返回多条记录 ( 使用动态游标 )

      Type mycur is ref cursor;-- 定义一个表类型

      -- 函数的定义

      Function emp_dept(dno number) return mycur;

End;

 

Create or replace package body mypack

As

Function emp_dept(dno number) return mycur

      Is

           Rc mycur;

      Begin

           Open rc for select * from emp where deptno=dno;

           Return rc;-- 结果集,也就是一张表

      End;

End;

 

调用程序包的存储过程:

Execute 程序包名 . 调用的名字 ( 函数或存储过程名 ) ( 参数 )

调用程序包的函数:

select 程序包名 . 调用的名字 ( 函数或存储过程名 ) ( 参数 ) from dual

select mypack.emp_dept(10) from dual;

 

// 编写一个程序包,做一个分页的操作,提供的参数 2 个,

第一个 pagesize 指定每页显示的记录数,第二个 page 指定要查询的页数

最后返回分好页的所有的记录

 

// 根据员工在各自部门的工资的排序情况,进行输出名次 ( 允许并列的情况出现 )

select deptno,ename,sal,(select count(*)+1 from emp where deptno=a.deptno and sal>a.sal) as 名次

from emp a order by deptno,sal desc;

这个题需要返回一个表,所以需要使用 程序包,但是可以不用游标来返回结果集

临时表 ( 表的结构是永久的,但其中的数据不能保存 )

Create global temporary table temp_emp(

  Deptno number ( 2 ) -- 部门

  Ename varchar2 ( 20 ) -- 姓名

  Sal number ( 7 , 2 ) -- 工资

  Ord number ( 2 ) -- 名次

) on commit delete rows

可以将程序包中返回的结果集插入到临时表中

创建程序包

create or replace package emp_pack

as

       type myrctype is ref cursor ; -- 创建一个表类型

       -- 建立一个统计排序的操作

       procedure p_emp;

       -- 返回结果级的操作

       function emp_order return myrctype ;

end ;

实现程序包

create or replace package body emp_pack

as

 

  -- 编写函数的实现

function emp_order return myrctype

    is

        rc myrctype;

    begin

-- 排序的操作

p_emp; -- 函数中调用存储过程

        open rc for select * from temp_emp;

    return rc;

end ;

 

-- 编写存储过程

    procedure p_emp

    as

-- 按照部门的排序

-- 创建一个部门的静态的游标

        cursor cc is select * from dept;

        ccrec cc% rowtype ; -- 创建部门的游标变量

-- 参数游标 , 专门负责部门的排序操作

cursor ck(no number is select * from emp where deptno=no order by sal desc ;

          ckrec ck% rowtype ;

         i number ;

         j number ;

         v_sal number :=- 1 ;

     begin

          for   ccrec in cc loop -- 按照部门循环 4

         i:= 0 ;

         for ckrec in ck(ccrec.deptno) loop

         i:=i+ 1 ; -- 记录当前的名次

-- 写入临时表

if ckrec.sal =  v_sal then

              null ;

         else

-- 名次的取值 ( 比较工资的操作 )

         j:=i; --j 是最终的名次

         end if ;

insert into temp_emp values (ccrec.deptno,ckrec.ename,ckrec.sal,j);

          v_sal:=ckrec.sal; -- 记录当前的工资

end loop ;

      end loop ;

     commit ;

  end ;

end ;

 

 

// 创建一个程序包,生成一个游标变量,可以装载整个 emp 表,

写一个向 emp 表中插入记录的方法

删除 emp 表记录的方法,如果该员工是该部门的最后一个人,删除这个员工后还要删除这个部门

接受一个部门号,可以把该部门的员工结果集返回出来

 

Create or replace package emp_all as

  Type cur_query_emp is ref cursor ;

  Function query_emp return cur_query_emp;

  Function emp_dept(dno number ) return cur_query_emp;

  procedure insert_emp(eno number ,ename varchar2 ,ejob varchar2 ,emgr number ,ehiredate date ,esal number ,ecomm number ,edeptno number );

  procedure delete_emp(dno number );

End ;

 

Create or replace package body emp_all

As

Function query_emp return cur_query_emp

  Is

    cqe cur_query_emp;

  Begin

    Open cqe for select * from emp;

    Return cqe;

  End ;

 

  Function emp_dept(dno number ) return cur_query_emp

    Is

       Rc cur_query_emp;

    Begin

       Open rc for select * from emp where deptno=dno;

       Return rc;

    End ;

 

  procedure insert_emp(eno number ,ename varchar2 ,ejob varchar2 ,emgr number ,ehiredate date ,esal number ,ecomm number ,edeptno number )

  as

  begin

    insert into emp values (eno,ename ,ejob,emgr,ehiredate,esal,ecomm,edeptno);

  end ;

End ;

 

 

一个员工号,返回他的工资和所在部门的平均工资

 

 

---------------------------------Oracle 的定时作业 --------------------------------

Oracle 的环境中,注册 pl/sql 的执行代码块,叫 Oracle 自动进行执行操作

应用:数据的汇总,备份 等操作按照设置自动执行

实现的步骤

1.      修改 Oracle 的配置文件 init.ora ,一般路径为

C:/Oracle/admin/ORA9i/pfile/init.ora.26201019350 Oracle 的作业是通过 SNP 进程处理的

寻找 # Job Queues # 为注释

如果 job_queue_processes=0 ,表示当前系统是不允许作业的,末尾设置为 10

job_queue_INTERVAL=60  表示操作间隔时间

2.      创建一张数据表

Create table test_table(

      Num_col number,

      Date_col date

)

3.      创建一个序列

Create sequence test_seq

      Start with 1

      Increment by 1

4.      编写 Oracle 要自动执行的代码,最好是写成存储过程

Create or replace procedure test_proc

As

Begin

Insert into test_table

values (test_seq.nextval,to_date( sysdate , 'yyyy-mm-dd' ));

commit ;

End ;

5.      对于每一个作业,都要求存在一个作业编号

Variable jobnumber number

6.      使用 Oracle 系统的作业包,注册作业的使用

Declare

jobnumber number ;

Begin

Dbms_job.submit(jobnumber, 'test_proc();' , sysdate , 'sysdate+90/(24*60*60)' );

end ;

--submit 表示注册一个作业

-- 参数为:系统分配给我一个作业编号,执行的 pl/sql 块的名字,从哪个时间开始运行,开始后间隔多少时间再次执行

Commit;

End;

7.      删除作业

Execute dbms_job.remove(21,ture,null);

 

 

------------------------------------------- 触发器 -----------------------------------------

触发器:加强约束条件额实现

实现级联操作

Create or replace trigger < 触发器的名字 >

      触发器的类型 after|before

      触发器的触发条件 insert|update|delete on 表名

For each now -- 是否是行级触发

When -- 表示附加的条件 , 用于改善触发器的执行的效率

Declare

Begin

Exception

End;

触发器中不能使用 commit rollback

 

emp 表中添加数据,如果 deptno 不存在,要求自动添加部门编号,而且要求部门的编号 >77

create or replace trigger t_emp;

before insert on emp

for each now

when (new.deptno>77 and new.ename='JONE')

declare

  n_count number;-- 是否存在的部门

begin

  select count(*) into n_count from dept where deptno=:new.deptno;

  if n_count=0 then

    insert into dept values(:new.deptno,' 人事 ',' 北京 ');

end;

 

日志表, log_table, 有三列   id number,ndate date operation varchar2

emp 表添加一个触发器,

如果 insert ,在 lob_table 体现出来 new.empno,sysdate,insert

Update , lob_table 体现出来 new.empno,sysdate,update

Delete, lob_table 体现出来 old.empno,sysdate,delete

 

create or replace trigger t_log

after insert or update or delete

on emp

for each row

declare

  new_empno emp.empno%type;

  old_empno emp.empno%type;

begin

  if inserting then

    new_empno:=:new.empno;

     DBMS_output.put_line(' 插入成功 ');

    insert into log_table values(new_empno,sysdate,'insert');

  end if;

  if updating then

    new_empno:=:new.empno;

    DBMS_output.put_line(' 更新成功 ');

    insert into log_table values(new_empno,sysdate,'update');

  end if;

  if deleting then

    old_empno:=:old.empno;

    DBMS_output.put_line(' 删除成功 ');

    insert into log_table values(old_empno,sysdate,'delete');

  end if;

end;

 

 

日志表, log_table, 有三列   id 序列, empno number ndate date emp 表所有字段

emp 表添加一个触发器,

当部门编号 =10 时,或者 dept loc= New York ’时,才允许向日志插入记录

 

 

emp 表中,创建一个触发器,在插入或者删除记录 ( 要求 deptno=10, 记录操作的时间,执行语句,设计员工号 )

日志的操作

创建日志表

Create table logtable(

      Serial number primary key,

      Dmltime date,

      Dmltype varchar2(20),

      Empno number

)

 

创建序列

Create sequence sql

创建触发器

Create or replace trigger tg

After insert or delete on emp

For each row   -- 表示行触发,并表示可以使用 new old ,记载了触发时每个行的状态

When (new.deptno= 10 or old.deptno= 10 )

Begin

If inserting then

  Insert into logtable values(sql.nextval,sysdate,'insert',:new.deptno);

Elsif deleting then

  Insert into logtable values (sql.nextval, sysdate , 'delete' ,:old.deptno);

End if ;

End ;

 

触发器还包括

视图触发器 ( 替代触发器 )

简单视图 ( 和表是一一对应的 )

复杂视图

      创建视图触发器

      Create or replace trigger myvtrig instead of 表示是一个视图级触发器

      Update on Myview( 视图名 )

      For each row

Is cursor cc is select * from emp were deptno=:new.deptno;

Begin

End;

 

数据库触发器

Create or replace trigger t1

--After startup on datebase 启动

--before shutdown datebase 关闭

 

 

----------------------------------------- 联动操作 -----------------------------------------

通过触发器,实现表之间的级联操作

库存表 kc

Pid 商品编号

Pname 商品名称

Pcount 库存数量

记录:

1 ibm 10

2 sony 15

3 hp 20

 

销售表 ( 流水表 ) sale

Pid 商品编号

Ptype 进货还是出货

Pcount 进出货的数量

 

操作销售表,添加记录,自动对库存进行修改

1 in 10  1 号库存增加 10 个数量

2 out 5  2 号商品出库 5

 

创建触发器

Create or replace trigger ttt

Before insert on sale

For each row

Begin

      If :new.ptype=’in’ then

           Update kc set Pcount=pcount+:new.pcount where pid=:New.pid;

      Else

           Update kc set Pcount=pcount-:new.pcount where pid=:New.pid;

      Raise_application_error(-20001,’’)

      End if;

End;

 

 

---------------------------------- ---------------------------------

锁的机制,也称为事务的处理

Update emp set sal=100 where empno=8000;

用户 1 执行了这句话后,会自动上锁,用户 2 在执行这句话就会处于静止的锁定状态

增删改操作执行后都是自动上锁,这种锁称为行锁

如何使用 select 来进行上锁

Select * from emp deptno=10 for update 

-- 这种锁叫做共享更新锁,对查询到的记录进行上锁

例题:订票的操作

北京 ----- 上海的火车票 3 张,但现在有 4 个订票人, 4 个人可能都在订票,有一个人肯定是订不到的,如何编写程序通过锁的机制让该程序运行正常

创建票务表

Create table ticket(

  Id number ( 3 ) primary key,

  route varchar2 ( 20 ) not null , -- 航线

  num number ( 3 ) -- 剩余票数

)

添加记录

insert into ticket values(1,' 北京 -- 上海 ',5);

编写一个存储过程,实现买票

create or replace procedure p_db(pid number ) is   --pid 航线编号

-- 订票之前要先查询一下余票

v_num number ; -- 余票变量

begin

      select num into v_num from ticket where id=pid for update ; -- 对查询结果上锁

      if v_num> 0 then

         update ticket set num=num- 1 where id=pid;

         commit ; -- 如过有票的时候,解锁

      else

         dbms_output.put_line( ' 卖完了 ' );

         rollback ; -- 如果票卖完了,解锁

      end if ;

end ;

 

使用 PL/SQL 的测试模式

进入 scott 用户的 sysdba 模式

connect scott/tiger as sysdba

给予 scott 用于调试程序的权限,不给权限否则会报错

grant debug any procedure,debug connect session to scott;

然后在返回 normal 模式,即可进行调试,

 

select num into v_num from ticket where id=pid for update wait 1 ;

wait 1 表示过 1 秒后查看程序是否能加上锁,不能加锁的话就停止加锁操作

---------------------------------Oracle 大表的处理 ---------------------------------

一张表记录很多,假设几百万条记录,如何来提高 select 的性能

即使是索引,也不能根本的解决问题

所以要使用分区的技术

将表视为一个硬盘,划出几个逻辑的区域来

在建表的时候,加上分区的技术,分区也是一种建表语句的使用

1.      范围分区

Create table emp1(

  Empno number ( 5 ) primary key,

  Ename varchar2 ( 20 )

)

Partition by range (empno) ( -- 创建分区

  Partition p1 values less than ( 3000 ),

  Partition p2 values less than ( 5000 ),

  partition p3 values less than (MAXVALUE) -- 指定超过 5000 范围的

--partition p3 values less than (to_date('20100604','yyyymmdd'))

-- 可以对日期或时间进行分区

)

 

如果 insert into emp1 values ( 1001 , '' ) ,将会插入 p1 区内

如果 insert into emp1 values ( 6001 , '' ) ,将会插入 p3 区内

查询的时候按照分区来查询,而不使用 where

select * from emp1 partition (p1);

范围的主要应用:时间

论坛的顶帖量可以达到几 W 的,如果要查帖子,就要按照时间来分区

医院会有很多人挂号,如果要查询某个挂号单,就要按照日期来查询

 

-- 添加分区

alter table 表名 add partition p4 values less than ( 3000 )

2.      散列分区

Create table ttt(

  deptno number ,

  dname varchar2 ( 10 ),

  loc varchar2 ( 10 )

)

Partition by hash (deptno) ( -- 创建分区

  Partition p1, Partition p2

)

3.      复合分区

先做范围分区,再在里边做子分区

Partition by range (empno) (

  subpartition by hash ()

)

4.      列表分区

Partition by list(area) (

  Partition north values ( ' 上海 ' , ' 广州 ' , ' 厦门 ' ),

  Partition west values ( ' 北京 ' , ' 天津 ' )

)

 

一般使用的最多的分区方法是范围,其次是散列

 

 

 

---------------------------------PL_SQLDeveloper 命令 ---------------------------------

1.      ed  打开文本编辑器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值