.连接命令
1.conn[ect]
用法:conn 用户名/密码@网络服务名[as sysdba/sysoper]当用特权用户身份连接时,必须带上as sysdba或是as sysoper
2.disc[onnect] 说明: 该命令用来断开与当前数据库的连接
3.psssw[ord]
说明: 该命令用于修改用户的密码,如果要想修改其它用户的密码,需要用sys/system登录。
4.show user 说明: 显示当前用户名
5.exit 说明: 该命令会断开与数据库的连接,同时会退出sql*plus
.文件操作命令
1.start和@ 说明: 运行sql脚本
案例: sql>@ d:\a.sql或是sql>start d:\a.sql
2.edit 说明: 该命令可以编辑指定的sql脚本
案例: sql>edit d:\a.sql,这样会把d:\a.sql这个文件打开
3.spool 说明: 该命令可以将sql*plus屏幕上的内容输出到指定文件中去。
案例: sql>spool d:\b.sql 并输入 sql>spool off
.交互式命令
1.&
说明:可以替代变量,而该变量在执行时,需要用户输入。
select * from emp where job='&job';
2.edit
说明:该命令可以编辑指定的sql脚本
案例:SQL>edit d:\a.sql
3.spool
说明:该命令可以将sql*plus屏幕上的内容输出到指定文件中去。
spool d:\b.sql 并输入 spool off
.显示和设置环境变量
概述:可以用来控制输出的各种格式,set show如果希望永久的保存相关的设置,可以去修改glogin.sql脚本
1.linesize
说明:设置显示行的宽度,默认是80个字符
show linesize
set linesize 90
2.pagesize说明:设置每页显示的行数目,默认是14
用法和linesize一样
至于其它环境参数的使用也是大同小异
3.oracle用户管理
.创建用户
概述:在oracle中要创建一个新的用户使用create user语句,一般是具有dba(数据库管理员)的权限才能使用。
create user 用户名 identified by 密码;
(oracle有个毛病,密码必须以字母开头,如果以字母开头,它不会创建用户)
.给用户修改密码
概述:如果给自己修改密码可以直接使用
password 用户名
如果给别人修改密码则需要具有dba的权限,或是拥有alter user的系统权限
SQL> alter user 用户名 identified by 新密码
.删除用户
概述:一般以dba的身份去删除某个用户,如果用其它用户去删除用户则需要具
有drop user的权限。
比如 drop user 用户名 【cascade】
在删除用户时,注意:
如果要删除的用户,已经创建了表,那么就需要在删除的时候带一个参数
cascade;
概述:创建的新用户是没有任何权限的,甚至连登陆的数据库的权限都没有,需
要为其指定相应的权限。给一个用户赋权限使用命令grant,回收权限使用命令revoke。
为了给讲清楚用户的管理,这里我给大家举一个案例。
SQL> conn xiaoming/m12;
ERROR:
ORA-01045: user XIAOMING lacks CREATE SESSION privilege; logon denied
警告: 您不再连接到 ORACLE。
SQL> show user;
USER 为 ""
SQL> conn system/p;
已连接。
SQL> grant connect to xiaoming;
授权成功。
SQL> conn xiaoming/m12;
已连接。
SQL>
注意:grant connect to xiaoming;在这里,准确的讲,connect不是权限,而
是角色。。 看图:
现在说下对象权限,现在要做这么件事情:
* 希望xiaoming用户可以去查询emp表
* 希望xiaoming用户可以去查询scott的emp表
grant select on emp to xiaoming
* 希望xiaoming用户可以去修改scott的emp表
grant update on emp to xiaoming
* 希望xiaoming用户可以去修改/删除,查询,添加scott的emp表
grant all on emp to xiaoming
* scott希望收回xiaoming对emp表的查询权限
revoke select on emp from xiaoming
//对权限的维护。
* 希望xiaoming用户可以去查询scott的emp表/还希望xiaoming可以把这个
权限继续给别人。
--如果是对象权限,就加入 with grant option
grant select on emp to xiaoming with grant option
我的操作过程:
SQL> conn scott/tiger;
已连接。
SQL> grant select on scott.emp to xiaoming with grant option;
授权成功。
SQL> conn system/p;
已连接。
SQL> create user xiaohong identified by m123;
用户已创建。
SQL> grant connect to xiaohong;
授权成功。
SQL> conn xiaoming/m12;
已连接。
SQL> grant select on scott.emp to xiaohong;
授权成功。
--如果是系统权限。
system给xiaoming权限时:
grant connect to xiaoming with admin option
问题:如果scott把xiaoming对emp表的查询权限回收,那么xiaohong会怎样?
答案:被回收。
下面是我的操作过程:
SQL> conn scott/tiger;
已连接。
SQL> revoke select on emp from xiaoming;
撤销成功。
SQL> conn xiaohong/m123;
已连接。
SQL> select * from scott.emp;
select * from scott.emp
*
第 1 行出现错误:
ORA-00942: 表或视图不存在
结果显示:小红受到诛连了。。
.使用 profile管理用户口令
概述:profile是口令限制,资源限制的命令集合,当建立数据库的,oracle会自动建立名称为default的profile。当建立用户没有指定profile选项,那么oracle就会将default分配给用户。
1.账户锁定
概述:指定该账户(用户)登陆时最多可以输入密码的次数,也可以指定用户锁定的时间(天)一般用dba的身份去执行该命令。
例子:指定scott这个用户最多只能尝试3次登陆,锁定时间为2天,让我们看看怎么实现。
创建profile文件
SQL> create profile lock_account limit failed_login_attempts 3
password_lock_time 2;
SQL> alter user scott profile lock_account;
2.给账户(用户)解锁
SQL> alter user tea account unlock;
3.终止口令
为了让用户定期修改密码可以使用终止口令的指令来完成,同样这个命令也需要
dba的身份来操作。
例子:给前面创建的用户tea创建一个profile文件,要求该用户每隔10天要修改自己的登陆密码,宽限期为2天。看看怎么做。
SQL> create profile myprofile limit password_life_time 10 password_grace_time 2;
SQL> alter user tea profile myprofile;
口令历史
概述:如果希望用户在修改密码时,不能使用以前使用过的密码,可使用口令历
史,这样oracle就会将口令修改的信息存放到数据字典中,这样当用户修改密码时,oracle就会对新旧密码进行比较,当发现新旧密码一样时,就提示用户重新输入密码。
例子:
1)建立profile
SQL>create profile password_history limit password_life_time 10
password_grace_time 2 password_reuse_time 10
password_reuse_time //指定口令可重用时间即10天后就可以重用
2)分配给某个用户
.删除 profile
概述:当不需要某个profile文件时,可以删除该文件。
SQL> drop profile password_history 【casade】
注意:文件删除后,用这个文件去约束的那些用户通通也都被释放了。。 加了casade,就会把级联的相关东西也给删除掉
4.oracle表的管理(数据类型,表创建删除,数据 CRUD操作)
oracle的表的管理
表名和列的命名规则
.必须以字母开头 .不能使用oracle的保留字
.长度不能超过30个字符 .只能使用如下字符 A-Z,a-z,0-9,$,#等
oracle支持的数据类型 .
字符类
char 定长 最大2000个字符。
例子:char(10) ‘小韩’前四个字符放‘小韩’,后添6个空格补全 如‘小韩 ’
varchar2(20) 变长 最大4000个字符。
例子:varchar2(10) ‘小韩’ oracle分配四个字符。这样可以节省空间。
clob(character large object) 字符型大对象 最大4G
char 查询的速度极快浪费空间,查询比较多的数据用。
varchar 节省空间
数字型.
number范围 -10的38次方 到 10的38次方 可以表示整数,也可以表示小数
number(5,2) 表示一位小数有5位有效数,2位小数 范围:-999.99到999.99
number(5) 表示一个5位整数 范围99999到-99999
. 日期类型
date 包含年月日和时分秒 oracle默认格式 1-1月-1999
timestamp 这是oracle9i对date数据类型的扩展。可以精确到毫秒。
图片.
blob 二进制数据 可以存放图片/声音 4G 一般来讲,在真实项目中是不会把图片和声音真的往数据库里存放,一般存放图片、视频的路径,如果安全需要比较高的话,则放入数据库。
建表.
--学生表
create table student ( ---表名
xh number(4), --学号
xm varchar2(20), --姓名
sex char(2), --性别
birthday date, --出生日期
sal number(7,2) --奖学金 ); --班级表
CREATE TABLE class(
classId NUMBER(2),
cName VARCHAR2(40)
);
修改表
添加一个字段.
SQL>ALTER TABLE student add (classId NUMBER(2));
. 修改一个字段的长度
SQL>ALTER TABLE student MODIFY (xm VARCHAR2(30));
. 修改字段的类型/或是名字(不能有数据) 不建议做
SQL>ALTER TABLE student modify (xm CHAR(30));
删除一个字段 不建议做(删了之后,顺序就变了。加就没问题,应为是加在后
面).
SQL>ALTER TABLE student DROP COLUMN sal;
修改表的名字 很少有这种需求.
SQL>RENAME student TO stu;
删除表.
SQL>DROP TABLE student;
添加数据
所有字段都插入数据.
INSERT INTO student VALUES ('A001', '张三', '男', '01-5月-05', 10);
oracle中默认的日期格式‘dd-mon-yy’ dd日子(天) mon 月份 yy 2位的年 ‘09-6月-99’ 1999年6月9日
修改日期的默认格式(临时修改,数据库重启后仍为默认;如要修改需要修改注册表)
ALTER SESSION SET NLS_DATE_FORMAT ='yyyy-mm-dd';
修改后,可以用我们熟悉的格式添加日期类型:
INSERT INTO student VALUES ('A002', 'MIKE', '男', '1905-05-06', 10);
插入部分字段.
INSERT INTO student(xh, xm, sex) VALUES ('A003', 'JOHN', '女');
插入空值.
INSERT INTO student(xh, xm, sex, birthday) VALUES ('A004', 'MARTIN', '男', null);
问题来了,如果你要查询student表里birthday为null的记录,怎么写sql呢?
错误写法:select * from student where birthday = null;
正确写法:select * from student where birthday is null;
如果要查询birthday不为null,则应该这样写:
select * from student where birthday is not null;
修改数据
修改一个字段. UPDATE student SET sex = '女' WHERE xh = 'A001';
修改多个字段. UPDATE student SET sex = '男', birthday = '1984-04-01' WHERE xh = 'A001';
修改含有null值的数据 不要用 = null 而是用 is null;
SELECT * FROM student WHERE birthday IS null;
删除数据.
DELETE FROM student;
删除所有记录,表结构还在,写日志,可以恢复的,速度慢。
Delete 的数据可以恢复。
savepoint a; --创建保存点
DELETE FROM student;
rollback to a; --恢复到保存点
一个有经验的DBA,在确保完成无误的情况下要定期创建还原点。
DROP TABLE student; --删除表的结构和数据;
delete from student WHERE xh = 'A001'; --删除一条记录;
truncate TABLE student; --删除表中的所有记录,表结构还在,不写日志,无法找回删除的记录,速度快。
5.oracle表查询(1)
oracle表基本查询
在我们讲解的过程中我们利用scott用户存在的几张表(emp,dept)为大家演示如何使用select语句,select语句在软件编程中非常有用,希望大家好好的掌握。
emp 雇员表
clerk 普员工
salesman 销售
manager 经理
analyst 分析师
president 总裁
mgr 上级的编号
hiredate 入职时间
sal 月工资
comm 奖金
deptno 部门 dept部门表
deptno 部门编号
accounting 财务部
research 研发部
operations 业务部
loc 部门所在地点
salgrade 工资级别
grade 级别
losal 最低工资
hisal 最高工资
查看表结构.
DESC emp;
查询所有列.
SELECT * FROM dept;
切忌动不动就用select *
SET TIMING ON; 打开显示操作时间的开关,在下面显示查询时间。
CREATE TABLE users(userId VARCHAR2(10), uName VARCHAR2 (20), uPassw
INSERT INTO users VALUES('a0001', '啊啊啊啊', 'aaaaaaaaaaaaaaaaaaaaaaa');
--从自己复制,加大数据量 大概几万行就可以了 可以用来测试sql语句执行效率
INSERT INTO users (userId,UNAME,UPASSW) SELECT * FROM users;
SELECT COUNT (*) FROM users;统计行数
查询指定列.
SELECT ename, sal, job, deptno FROM emp;
如何取消重复行DISTINCT .
SELECT DISTINCT deptno, job FROM emp;
?查询SMITH所在部门,工作,薪水
SELECT deptno,job,sal FROM emp WHERE ename = 'SMITH';
注意:oracle对内容的大小写是区分的,所以ename='SMITH'和ename='smith'是不同的
使用算术表达式 . nvl null
问题:如何显示每个雇员的年工资?
SELECT sal*13+nvl(comm, 0)*13 "年薪" , ename, comm FROM emp;
使用列的别名.
SELECT ename "姓名", sal*12 AS "年收入" FROM emp;
如何处理null值 .
使用nvl函数来处理
如何连接字符串(||).
SELECT ename || ' is a ' || job FROM emp;
使用where子句 .
问题:如何显示工资高于3000的 员工?
SELECT * FROM emp WHERE sal > 3000;
问题:如何查找1982.1.1后入职的员工?
SELECT ename,hiredate FROM emp WHERE hiredate >'1-1月-1982';
问题:如何显示工资在2000到3000的员工?
SELECT ename,sal FROM emp WHERE sal >=2000 AND sal <= 3000;
. 如何使用like操作符
%:表示0到多个字符
_:表示任意单个字符
问题:如何显示首字符为S的员工姓名和工资?
SELECT ename,sal FROM emp WHERE ename like 'S%';
如何显示第三个字符为大写O的所有员工的姓名和工资?
SELECT ename,sal FROM emp WHERE ename like '__O%';
在where条件中使用in .
问题:如何显示empno为7844, 7839,123,456 的雇员情况?
SELECT * FROM emp WHERE empno in (7844, 7839,123,456);
使用is null的操作符 .
问题:如何显示没有上级的雇员的情况?
错误写法:select * from emp where mgr = '';
正确写法:SELECT * FROM emp WHERE mgr is null;
6.oracle表查询(2)
使用逻辑操作符号.
问题:查询工资高于500或者是岗位为MANAGER的雇员,同时还要满足他们的姓名首字母为大写的J?
SELECT * FROM emp WHERE (sal >500 or job = 'MANAGER') and ename LIKE 'J%';
使用order by . 字句 默认asc
问题:如何按照工资的从低到高的顺序显示雇员的信息?
SELECT * FROM emp ORDER by sal;
问题:按照部门号升序而雇员的工资降序排列
SELECT * FROM emp ORDER by deptno, sal DESC;
使用列的别名排序.
问题:按年薪排序
select ename, (sal+nvl(comm,0))*12 "年薪" from emp order by "年薪" asc;
别名需要使用“”号圈中,英文不需要“”号
Clear 清屏命令
oracle表复杂查询
数据分组 ——max,min, avg, sum, count
问题:如何显示所有员工中最高工资和最低工资?
SELECT MAX(sal),min(sal) FROM emp e;
最高工资那个人是谁?
错误写法:select ename, sal from emp where sal=max(sal);
正确写法:select ename, salfrom empwhere sal=(select max(sal) fromemp);
注意:select ename, max(sal) from emp;这语句执行的时候会报错,说
ORA-00937:非单组分组函数。因为max是分组函数,而ename不是分组函数.......
但是select min(sal), max(sal) from emp;这句是可以执行的。因为min和 max都是分组函数,就是说:如果列里面有一个分组函数,其它的都必须是分组函数,否则就出错。这是语法规定的
问题:如何显示所有员工的平均工资和工资总和?
问题:如何计算总共有多少员工问题:如何
扩展要求:
查询最高工资员工的名字,工作岗位
SELECT ename, job, sal FROM emp e where sal = (SELECT MAX(sal) FROM emp);
显示工资高于平均工资的员工信息
SELECT * FROM emp e where sal > (SELECT AVG(sal) FROM emp);
group by 和 having子句 .
group by用于对查询的结果分组统计,
having子句用于限制分组显示结果。
问题:如何显示每个部门的平均工资和最高工资?
SELECT AVG(sal), MAX(sal), deptno FROM emp GROUP by deptno;
(注意:这里暗藏了一点,如果你要分组查询的话,分组的字段deptno一定要出现在查询的列表里面,否则会报错。因为分组的字段都不出现的话,就没办法分组了)
问题:显示每个部门的每种岗位的平均工资和最低工资?
SELECT min(sal), AVG(sal), deptno, job FROM emp GROUP by deptno, job;
问题:显示平均工资低于2000的部门号和它的平均工资?
SELECT AVG(sal), MAX(sal), deptno FROM emp GROUP by deptno having AVG(sal) < 2000;
对数据分组的总结.
1 分组函数只能出现在选择列表、having、order by子句中(不能出现在where中)
2 如果在select语句中同时包含有group by, having, order by 那么它们的顺序是group by, having, order by
3 在选择列中如果有列、表达式和分组函数,那么这些列和表达式必须有一个出现在group by 子句中,否则就会出错。
如SELECT deptno, AVG(sal), MAX(sal) FROM emp GROUP by deptno HAVING
AVG(sal) < 2000;
这里deptno就一定要出现在group by 中
多表查询
多表查询是指基于两个和两个以上的表或是视图的查询。在实际应用中,查询单个表可能不能满足你的需求,(如显示sales部门位置和其员工的姓名),这种情况下需要使用到(dept表和emp表)
问题:显示雇员名,雇员工资及所在部门的名字【笛卡尔集】?
规定:多表查询的条件是 至少不能少于 表的个数-1 才能排除笛卡尔集
(如果有N张表联合查询,必须得有N-1个条件,才能避免笛卡尔集合)
SELECT e.ename, e.sal, d.dname FROM emp e, dept d WHERE e.deptno = d.deptno;
问题:显示部门号为10的部门名、员工名和工资?
SELECT d.dname, e.ename, e.sal FROM emp e, dept d WHERE e.deptno = d.deptno
and e.deptno = 10;
问题:显示各个员工的姓名,工资及工资的级别?
先看salgrade的表结构和记录
SQL>select * from salgrade;
GRADE LOSAL HISAL
1 700 1200
2 1201 1400
3 1401 2000
4 2001 3000
5 3001 9999
SELECT e.ename, e.sal, s.grade FROM emp e, salgrade s WHERE e.sal BETWEEN
s.losal AND s.hisal;
扩展要求:
问题:显示雇员名,雇员工资及所在部门的名字,并按部门排序?
SELECT e.ename, e.sal, d.dname FROM emp e, dept d WHERE e.deptno = d.deptno
ORDER by e.deptno;
(注意:如果用group by,一定要把e.deptno放到查询列里面)
自连接.
自连接是指在同一张表的连接查询
问题:显示某个员工的上级领导的姓名?
比如显示员工‘FORD’的上级
SELECT worker.ename, boss.ename FROM emp worker,emp boss WHERE worker.mgr
= boss.empno AND worker.ename = 'FORD';
子查询
子查询是指嵌入在其他sql语句中的select语句,也叫嵌套查询。
. 单行子查询
单行子查询是指只返回一行数据的子查询语句
请思考:显示与SMITH同部门的所有员工?
思路:
1 查询出SMITH的部门号: select deptno from emp WHERE ename = 'SMITH';
2 显示: SELECT * FROM emp WHERE deptno = (select deptno from emp WHERE ename =
'SMITH');
数据库在执行sql 是从左到右扫描的, 如果有括号的话,括号里面的先被优先执行。
多行子查询.
多行子查询指返回多行数据的子查询
请思考:如何查询和部门10的工作相同的雇员的名字、岗位、工资、部门号
SELECT DISTINCT job FROM emp WHERE deptno = 10;
SELECT * FROM emp WHERE job IN (SELECT DISTINCT job FROM emp WHERE deptno
= 10); (注意:不能用job=..,因为等号=是一对一的)
在多行子查询中使用all操作符 .
问题:如何显示工资比部门30的所有员工的工资高的员工的姓名、工资和部门号?
SELECT ename, sal, deptno FROM emp WHERE sal > all (SELECT sal FROM emp
WHERE deptno = 30);
扩展要求: 大家想想还有没有别的查询方法。
SELECT ename, sal, deptno FROM emp WHERE sal > (SELECT MAX(sal) FROM emp WHERE deptno = 30); 执行效率上, 函数高得多
在多行子查询中使用any操作符 .
问题:如何显示工资比部门30的任意一个员工的工资高的员工姓名、工资和部门号?
SELECT ename, sal, deptno FROM emp WHERE sal > ANY (SELECT sal FROM emp WHERE deptno = 30);
扩展要求: 大家想想还有没有别的查询方法。
SELECT ename, sal, deptno FROM emp WHERE sal > (SELECT min(sal) FROM emp WHERE deptno = 30);
多列子查询.
单行子查询是指子查询只返回单列、单行数据,多行子查询是指返回单列多行数
据,都是针对单列而言的,而多列子查询是指查询返回多个列数据的子查询语句。
请思考如何查询与SMITH的部门和岗位完全相同的所有雇员。
SELECT deptno, job FROM emp WHERE ename = 'SMITH';
SELECT * FROM emp WHERE (deptno, job) = (SELECT deptno, job FROM emp WHERE
ename = 'SMITH');
在from子句中使用子查询 .
请思考:如何显示高于自己部门平均工资的员工的信息 思路:
1. 查出各个部门的平均工资和部门号
SELECT deptno, AVG(sal) mysal FROM emp GROUP by deptno;
2. 把上面的查询结果看做是一张子表
SELECT e.ename, e.deptno, e.sal, ds.mysal FROM emp e, (SELECT deptno,
AVG(sal) mysal FROM emp GROUP by deptno) ds WHERE e.deptno = ds.deptno
AND e.sal > ds.mysal;
小总结:
在这里需要说明的当在from子句中使用子查询时,该子查询会被作为一个视图来对待,因此叫做内嵌视图,当在from子句中使用子查询时,必须给子查询指定别名。
注意:别名不能用as,如:SELECT e.ename, e.deptno, e.sal, ds.mysal FROM emp e, (SELECT deptno, AVG(sal) mysal FROM emp GROUP by deptno) as ds WHERE e.deptno = ds.deptno AND e.sal > ds.mysal;
在ds前不能加as,否则会报错 (给表取别名的时候,不能加as;但是给列取别名,是可以加as的)
分页查询.
按雇员的id号升序取出
oracle的分页一共有三种方式
1.根据rowid来分
select * from t_xiaoxi where rowid in (select rid from (select rownum
rn, rid from(select rowid rid, cid from t_xiaoxi order by cid desc) where
rownum<10000) where rn>9980) order by cid desc;
执行时间0.03秒
2.按分析函数来分
select * from (select t.*, row_number() over(order by cid desc) rk from
t_xiaoxi t) where rk<10000 and rk>9980;
执行时间1.01秒
3.按rownum来分
select * from (select t.*,rownum rn from(select * from t_xiaoxi order
by cid desc)t where rownum<10000) where rn>9980;
执行时间0.1秒
其中t_xiaoxi为表名称,cid为表的关键字段,取按cid降序排序后的第9981-9999条记录,t_xiaoxi表有70000多条记录。
个人感觉1的效率最好,3次之,2最差。
//测试通过的分页查询okokok
select * from (select a1.*, rownum rn from(select ename,job from emp) a1 where rownum<=10)where rn>=5;
下面最主要介绍第三种:按rownum来分
1. rownum 分页
SELECT * FROM emp;
2. 显示rownum[oracle分配的]
SELECT e.*, ROWNUM rn FROM (SELECT * FROM emp) e;
rn相当于Oracle分配的行的ID号
3.挑选出6—10条记录
先查出1-10条记录
SELECT e.*, ROWNUM rn FROM (SELECT * FROM emp) e WHERE ROWNUM <= 10;
如果后面加上rownum>=6是不行的,
4. 然后查出6-10条记录
SELECT * FROM (SELECT e.*, ROWNUM rn FROM (SELECT * FROM emp) e WHERE ROWNUM <= 10) WHERE rn >= 6;
5. 几个查询变化
a. 指定查询列,只需要修改最里层的子查询
只查询雇员的编号和工资
SELECT * FROM (SELECT e.*, ROWNUM rn FROM (SELECT ename, sal FROM emp)
e WHERE ROWNUM <= 10) WHERE rn >= 6;
b. 排序查询,只需要修改最里层的子查询
工资排序后查询6-10条数据
SELECT * FROM (SELECT e.*, ROWNUM rn FROM (SELECT ename, sal FROM emp ORDER
by sal) e WHERE ROWNUM <= 10) WHERE rn >= 6;
用查询结果创建新表.
这个命令是一种快捷的建表方式
CREATE TABLE mytable (id, name, sal, job, deptno) as SELECT empno, ename,
sal, job, deptno FROM emp;
创建好之后,desc mytable;和select * from mytable;看看结果如何?
合并查询.
有时在实际应用中,为了合并多个select语句的结果,可以使用集合操作符号
union,union all,intersect,minus
多用于数据量比较大的数据局库,运行速度快。
1). union
该操作符用于取得两个结果集的并集。当使用该操作符时,会自动去掉结果集中
重复行。
SELECT ename, sal, job FROM emp WHERE sal >2500
UNION
SELECT ename, sal, job FROM emp WHERE job = 'MANAGER';
2).union all
该操作符与union相似,但是它不会取消重复行,而且不会排序。
SELECT ename, sal, job FROM emp WHERE sal >2500
UNION ALL
SELECT ename, sal, job FROM emp WHERE job = 'MANAGER';
该操作符用于取得两个结果集的并集。当使用该操作符时,会自动去掉结果集中重复行。
3). intersect
使用该操作符用于取得两个结果集的交集。
SELECT ename, sal, job FROM emp WHERE sal >2500
INTERSECT
SELECT ename, sal, job FROM emp WHERE job = 'MANAGER';
4). minus (MINUS就是减法的意思)
使用改操作符用于取得两个结果集的差集,他只会显示存在第一个集合中,而不存在第二个集合中的数据。
SELECT ename, sal, job FROM emp WHERE sal >2500
MINUS
SELECT ename, sal, job FROM emp WHERE job = 'MANAGER';
创建数据库有两种方法:
1). 通过oracle提供的向导工具。√database Configuration Assistant 【数据库配置助手】
2).我们可以用手工步骤直接创建。
7.java操作 oracle
1.上节回顾
2.java程序如何操作oracle √
3.如何在oracle中操作数据
4.oracle事务处理
5.sql函数的使用 √ 期望目标
1.掌握oracle表对数据操作技巧
2.掌握在java程序中操作oracle
3.理解oracle事物概念
4.掌握oracle各种sql函数
java连接oracle
下面我们举例说明,写一个java,分页显示emp表的用户信息。
Java代码 (1)
1. package com.sp;
2.
3. import java.sql.Connection;
4. import java.sql.DriverManager;
5. import java.sql.ResultSet;
6. import java.sql.Statement;
7.
8.//演示 如何使用 jdbc_odbc桥连接方式
9. public class TestOracle {
10.
11. public static void main(String[] args) {
12. try {
13.
14. // 1.加载驱动
15. Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
16.
17. // 2.得到连接
18. Connection ct = DriverManager.getConnection(
19.
"jdbc.odbc:testConnectOracle", "scott",
21."tiger");
22.
23. // 从下面开始,和SQL Server一模一样
24. Statement sm = ct.createStatement();
25.
ResultSet rs = sm.executeQuery("select * from emp")
;
26. while (rs.next()) {
27.
//用户名
28.
System.out.println("用户
名: "+rs.getString(2));
29.
//默认是从1开始编号的
30. }
31. } catch (Exception e) {
32. e.printStackTrace();
33. }
34. }
35.}
在得到连接那里,要去配置数据源,点击控制面板-->系统和安全-->管理工具-->数据源(ODBC),
注:在windows7中使用ODBCAB32在DOS运行打开ODBC
这里要注意:jdbcodbc能不能远程连接呢?不能远程连接,也就是你这样写的话就意味着java程 序和oracle数据库应该是在同一台机器上,因为这里没有指定IP地址,肯定默认就是本地。 如果要远程连,就用jdbc,jdbc是可以远程连的。
运行TestOracle.java,控制台输出.......................
可惜我没运行成功,说
java.sql.SQLException: No suitable driver found for
jdbc.odbc:testConnectOracle
at java.sql.DriverManager.getConnection(Unknown Source)
at java.sql.DriverManager.getConnection(Unknown Source)
at com.sp.TestOracle.main(TestOracle.java:18)
不知道为什么。。。
接下来讲解用JDBC的方式连接Oracle
记得要把驱动包引入,classes12.jar
运行,。。。。 再次可惜,我还是没运行成功,错误是:
java.sql.SQLException: Io 异常: The Network Adapter could not establish the
接下来建个web project,来测试oracle的分页,挺麻烦,不记录了。。
在oracle中操作数据 - 使用特定格式插入日期值
使用 to_date函数 .
请大家思考: 如何插入列带有日期的表,并按照年-月-日的格式插入?
insert into emp values (9998, 'xiaohong', 'MANAGER', 7782, to_date('1988-12-12', 'yyyy-mm-dd'), 78.9, 55.33, 10);
注意:
insert into emp values (9998, 'xiaohong', 'MANAGER', 7782, '12-12月-1988', 78.9, 55.33, 10);
这句语句是可以成功运行的
使用子查询插入数据
介绍.
当使用valus子句时,一次只能插入一行数据,当使用子查询插入数据时,一条
inset语句可以插入大量的数据。当处理行迁移或者装载外部表的数据到数据库时,可以使用子查询来插入数据。
把emp表中10号部门的数据导入到新表中
create table kkk(myId number(4), myName varchar2(50), myDept number(5));
insert into kkk (myId, myName, myDept) select empno, ename, deptno from emp where deptno = 10;
使用update语句更新数据时,既可以使用表达式或者数值直接修改数据,也可以使用子查询修改数据。
问题:希望员工SCOTT的岗位、工资、补助与 SMITH员工一样。
update emp set(job, sal, comm)=(select job, sal, comm from emp where ename='SMITH') where ename='SCOTT';
8.oracle中事务处理
什么是事务.
事务用于保证数据的一致性,它由一组相关的dml语句组成,该组的dml(数据操作语言,增删改,没有查询)语句要么全部成功,要么全部失败。
如:网上转账就是典型的要用事务来处理,用于保证数据的一致性。
dml 数据操作语言
银行转账、QQ申请、车票购买
事务和锁.
当执行事务操作时(dml语句),oracle会在被作用的表上加锁,防止其它用户修改表的结构。这里对我们的用户来来讲是非常重要的。 .....其它进程排序,知道1号进程完成,锁打开,2号进程进入。依次进行,如果有进程级别较高的,可以插队。
提交事务.
当执行用commit语句可以提交事务。当执行了commit语句之后,会确认事务的变化、结束事务。删除保存点、释放锁,当使用commit语句结束事务之后,其它会话将可以查看到事务变化后的新数据。
保存点就是为回退做的。保存点的个数没有限制
回退事务.
在介绍回退事务前,我们先介绍一下保存点(savepoint)的概念和作用。保存点是事务中的一点。用于取消部分事务,当结束事务时,会自动的删除该事务所定义的所有保存点。当执行rollback时,通过指定保存点可以回退到指定的点,
这里我们作图说明。
事务的几个重要操作.
1.设置保存点 savepoint a
2.取消部分事务 rollback to a
3.取消全部事务 rollback
注意:这个回退事务,必须是没有commit前使用的;如果事务提交了,那么无论你刚才做了多少个保存点,都统统没有。
如果没有手动执行commit,而是exit了,那么会自动提交
java程序中如何使用事务 .
在java操作数据库时,为了保证数据的一致性,比如账户操作(1)从一个账户
中减掉10$(2)在另一个账户上加入10$,我们看看如何使用事务?
Java代码
1. package com.sp;
3. import java.sql.Connection;
4.import java.sql.DriverManager;
5. import java.sql.ResultSet;
6. import java.sql.Statement;
8. public class TestTrans {
10. public static void main(String[] args) {
11. try {
13. // 1.加载驱动
Class.forName("oracle.jdbc.driver.OracleDriver");
16. // 2.得到连接
17. Connection ct = DriverManager.getConnection(
18.
"jdbc:oracle:thin:@127.0.0.1:15
21:orcl", "s
cott", "tiger");
19.
20. Statement sm = ct.createStatement();
22. // 从scott的sal中减去100
sm.executeUpdate("update emp set sal=sal-100 where
ename='SCOTT'");
24.
25. int i = 7 / 0;
26.
27. // 给smith的sal加上100
sm.executeUpdate("update emp set sal=sal+100 where
ename='SMITH'");
30. // 关闭打开的资源
31. sm.close();
32. ct.close();
33. } catch (Exception e) {
34. e.printStackTrace();
35. }
37. }
39.}
运行,会出现异常,查看数据库,SCOTT的sal减了100,但是SMITH的sal却不变,很可怕。。。
我们怎样才能保证,这两个操作要么同时成功,要么同时失败呢?
Java代码
1. package com.sp;
2.
3. import java.sql.Connection;
4. import java.sql.DriverManager;
5. import java.sql.SQLException;
6. import java.sql.Statement;
7.
8. public class TestTrans {
9.
10. public static void main(String[] args) {
11. Connection ct = null;
12. try {
13. // 1.加载驱动
14. Class.forName("oracle.jdbc.driver.OracleDriver");
15.
16. // 2.得到连接
17. ct = DriverManager.getConnection(
18.
"jdbc:oracle:thin:@127.0.0.1:1521:orcl", "s
cott", "tiger");
19.
20. // 加入事务处理
21. ct.setAutoCommit(false);// 设置不能默认提交
22.
23. Statement sm = ct.createStatement();
24.
25. // 从scott的sal中减去100
26.
sm.executeUpdate("update emp set sal=sal-100 where
ename='SCOTT'");
27.
28. int i = 7 / 0;
29.
30. // 给smith的sal加上100
31.
sm.executeUpdate("update emp set sal=sal+100 where
ename='SMITH'");
32.
33. // 提交事务
34. ct.commit();
35.
36. // 关闭打开的资源
37. sm.close();
38. ct.close();
39. } catch (Exception e) {
40. // 如果发生异常,就回滚
41. try {
42.
ct.rollback();
43. } catch (SQLException e1) {
44.
e1.printStackTrace();
45. }
46. e.printStackTrace();
47. }
48.
49. }
50.
51.}
再运行一下,会出现异常,查看数据库,数据没变化。。
只读事务.
只读事务是指只允许执行查询的操作,而不允许执行任何其它dml操作的事务,使用只读事务可以确保用户只能取得某时间点的数据。假定机票代售点每天18点开始统计今天的销售情况,这时可以使用只读事务。在设置了只读事务后,尽 管其它会话可能会提交新的事务,但是只读事务将不会取得最新数据的变化,从而可以保证取得特定时间点的数据信息。 设置只读事务.
set transaction read only;
9.oracle的函数
sql函数的使用
字符函数 .
介绍
字符函数是oracle中最常用的函数,我们来看看有哪些字符函数:
.lower(char):将字符串转化为小写的格式。
. upper(char):将字符串转化为大写的格式。
.substr(char,m,n):取字符串的子串 n代表取n个的意思,不是代表取到第n个 . replace(char1,search_string,replace_string)
.length(char):返回字符串的长度。
. instr(char1,char2,[,n[,m]])取子串在字符串的位置
问题:将所有员工的名字按小写的方式显示
SQL> select lower(ename) from emp;
问题:将所有员工的名字按大写的方式显示。
SQL> select upper(ename) from emp;
问题:显示正好为5个字符的员工的姓名。
SQL> select * from emp where length(ename)=5;
问题:显示所有员工姓名的前三个字符。
SQL> select substr(ename,1,3) from emp;
问题:以首字母大写,后面小写的方式显示所有员工的姓名。
SQL> select upper(substr(ename,1,1)) ||
lower(substr(ename,2,length(ename)-1)) from emp;
问题:以首字母小写,后面大写的方式显示所有员工的姓名。
SQL> select lower(substr(ename,1,1)) ||
upper(substr(ename,2,length(ename)-1)) from emp;
问题:显示所有员工的姓名,用“我是老虎”替换所有“A”
SQL> select replace(ename,'A', '我是老虎') from emp;
数学函数
数学函数的输入参数和返回值的数据类型都是数字类型的。数学函数包括cos,cosh,exp,ln, log,sin,sinh,sqrt,tan,tanh,acos,asin,atan,round,
我们讲最常用的:
. round(n,[m]). 该函数用于执行四舍五入,如果省掉m,则四舍五入到整数,如果m是正数,则四舍五入到小数点的 m位后。如果 m是负数,则四舍五入到小数点的m位前。
. trunc(n,[m]) 该函数用于截取数字。如果省掉m,就截去小数部分,如果 m是正数就截取到小数点的m位后,如果 m是负数,则截取到小数点的前 m位。
. mod(m,n)
. floor(n) 返回小于或是等于n的最大整数.
. ceil(n) 返回大于或是等于n的最小整数.
对数字的处理,在财务系统或银行系统中用的最多,不同的处理方法,对财务报表有不同的结果。
问题:显示在一个月为30天的情况下,所有员工的日薪金,忽略余数。
SQL> select trunc(sal/30), ename from emp;
or
SQL> select floor(sal/30), ename from emp;
在做oracle测试的时候,可以使用dual表
select mod(10,2) from dual;结果是0
select mod(10,3) from dual;结果是1
其它的数学函数,有兴趣的同学可以自己去看看:
abs(n): 返回数字n的绝对值
select abs(-13) from dual;
acos(n): 返回数字的反余弦值
asin(n): 返回数字的反正弦值
atan(n): 返回数字的反正切值 cos(n):
exp(n): 返回e的n次幂
log(m,n): 返回对数值
power(m,n): 返回m的n次幂
日期函数 .
日期函数用于处理date类型的数据。
默认情况下日期格式是dd-mon-yy 即12-7月-78
(1)sysdate: 该函数返回系统时间 (2)add_months(d,n) (3)last_day(d):返回指定日期所在月份的最后一天
问题:查找已经入职8个月多的员工
SQL> select * from emp where sysdate>=add_months(hiredate,8);
问题:显示满10年服务年限的员工的姓名和受雇日期。
SQL> select ename, hiredate from emp where
sysdate>=add_months(hiredate,12*10);
问题:对于每个员工,显示其加入公司的天数。
SQL> select floor(sysdate-hiredate) "入职天数",ename from emp;
or
SQL> select trunc(sysdate-hiredate) "入职天数",ename from emp;
问题:找出各月倒数第3天受雇的所有员工。
SQL> select hiredate,ename from emp where last_day(hiredate)-2=hiredate;
转换函数
转换函数用于将数据类型从一种转为另外一种。在某些情况下,oracle server允许值的数据类型和实际的不一样,这时oracle server会隐含的转化数据类型
比如:
create table t1(id int);
insert into t1 values('10');-->这样oracle会自动的将'10' -->10
create table t2 (id varchar2(10));
insert into t2 values(1); -->这样oracle就会自动的将1 -->'1';
我们要说的是尽管oracle可以进行隐含的数据类型的转换,但是它并不适应所有的情况,为了提高程序的可靠性,我们应该使用转换函数进行转换。
to_char.
你可以使用select ename, hiredate, sal from emp where deptno = 10;显示信息,可是,在某些情况下,这个并不能满足你的需求。
问题:日期是否可以显示 时/分/秒
SQL> select ename, to_char(hiredate, 'yyyy-mm-dd hh24:mi:ss') from emp;
问题:薪水是否可以显示指定的货币符号
SQL>
yy:两位数字的年份 2004-->04
yyyy:四位数字的年份 2004年
mm:两位数字的月份 8月-->08
dd:两位数字的天 30号-->30
hh24: 8点-->20
hh12:8点-->08
mi、ss-->显示分钟\秒 9:显示数字,并忽略前面0
0:显示数字,如位数不足,则用0补齐
.:在指定位置显示小数点
,:在指定位置显示逗号 $:在数字前加美元
L:在数字前面加本地货币符号
C:在数字前面加国际货币符号
G:在指定位置显示组分隔符、
D:在指定位置显示小数点符号(.)
问题:显示薪水的时候,把本地货币单位加在前面
SQL> select ename, to_char(hiredate, 'yyyy-mm-dd hh24:mi:ss'),
to_char(sal,'L99999.99') from emp;
问题:显示1980年入职的所有员工
SQL> select * from emp where to_char(hiredate, 'yyyy')=1980;
问题:显示所有12月份入职的员工
SQL> select * from emp where to_char(hiredate, 'mm')=12;
to_date.
函数to_date用于将字符串转换成date类型的数据。
问题:能否按照中国人习惯的方式年—月—日添加日期。
系统函数
sys_context.
1)terminal:当前会话客户所对应的终端的标示符
2)lanuage: 语言
3)db_name: 当前数据库名称
4)nls_date_format: 当前会话客户所对应的日期格式 5)session_user: 当前会话客户所对应的数据库用户名
6)current_schema: 当前会话客户所对应的默认方案名
7)host: 返回数据库所在主机的名称
通过该函数,可以查询一些重要信息,比如你正在使用哪个数据库?
select sys_context('USERENV','db_name') from dual;
注意:USERENV是固定的,不能改的,db_name可以换成其它,
比如select sys_context('USERENV','lanuage') from dual;
又比如select sys_context('USERENV','current_schema') from dual;
10.数据库管理,表的逻辑备份与恢复
1.上节回顾
2.数据库管理员 3.数据库(表)的逻辑备份与恢复 √
4.数据字典和动态性能视图 √
5.管理表空间和数据文件 √
数据库管理员
介绍.
每个oracle数据库应该至少有一个数据库管理员(dba),对于一个小的数据库,一个dba就够了,但是对于一个大的数据库可能需要多个dba分担不同的管理职责。那么一个数据库管理员的主要工作是什么呢:
管理数据库的用户主要是sys和system .
(sys好像是董事长,system好像是总经理,董事长比总经理大,但是通常是总经理干事)
在前面我们已经提到这两个用户,区别主要是:
1.最重要的区别,存储的数据的重要性不同
sys:所有oracle的数据字典的基表和视图都存放在sys用户中,这些基表和视图对于oracle的运行是至关重要的,由数据库自己维护,任何用户都不能手动更改。sys用户拥有dba,sysdba,sysoper角色或权限,是oracle权限最高的用户。
system:用于存放次一级的内部数据,如oracle的一些特性或工具的管理信息。system用户拥有dba,sysdba角色或系统权限。
sysdba可以建数据库,sysoper不能建数据库
2. 其次的区别,权限的不同。
sys用户必须以 as sysdba或as sysoper形式登录。不能以normal方式登录数据库 system如果正常登录,它其实就是一个普通的 dba用户,但是如果以 as sysdba登录,其结果实际上它是作为sys用户登录的,从登录信息里面我们可以看出来。sysdba和sysoper权限区别图,看图:
sysdba>sysoper>dba
可以看到:只要是sysoper拥有的权限,sysdba都有;蓝色是它们区别的地方。
(它们的最大区别是:sysdba可以创建数据库,sysoper不可以创建数据库)
dba权限的用户 .
dba用户是指具有dba角色的数据库用户。特权用户可以执行启动实例,关闭实例等特殊操作,而dba用户只有在启动数据库后才能执行各种管理工作。
(相当于说dba连startup和shutdown这两个权限都没有)
两个主要的用户,三个重要权限,他们的区别和联系,大家要弄清楚
管理初始化参数
. 管理初始化参数(调优的一个重要知识点,凭什么可以对数据库进行调优呢?
是因为它可以对数据库的一些参数进行修改修正)
初始化参数用于设置实例或是数据库的特征。oracle9i提供了200多个初始化参数,并且每个初始化参数都有默认值。
显示初始化参数.
(1) show parameter命令
如何修改参数.
需要说明的如果你希望修改这些初始化的参数,可以到文件D:\oracle\admin\myoral\pfile\init.ora文件中去修改比如要修改实例的名字
数据库(表)的逻辑备份与恢复
介绍.
逻辑备份是指使用工具export将数据对象的结构和数据导出到文件的过程,逻辑恢复是指当数据库对象被误操作而损坏后使用工具import利用备份的文件把数据对象导入到数据库的过程。
物理备份即可在数据库open的状态下进行也可在关闭数据库后进行,但是逻辑备份和恢复只能在open的状态下进行。
导出.
导出具体的分为:导出表,导出方案,导出数据库三种方式。
导出使用exp命令来完成的,该命令常用的选项有:
userid: 用于指定执行导出操作的用户名,口令,连接字符串
tables: 用于指定执行导出操作的表
owner: 用于指定执行导出操作的方案 full=y: 用于指定执行导出操作的数据库
inctype: 用于指定执行导出操作的增量类型
rows: 用于指定执行导出操作是否要导出表中的数据
file: 用于指定导出文件名
导出表.
1.导出自己的表
exp userid=scott/tiger@myoral tables=(emp,dept) file=d:\e1.dmp
2.导出其它方案的表
如果用户要导出其它方案的表,则需要dba的权限或是exp_full_database的权限,比如system就可以导出scott的表
E:\oracle\ora92\bin>exp userid=system/manager@myoral tables=(scott.emp) file=d:\e2.emp
特别说明:在导入和导出的时候,要到oracle目录的bin目录下。
3. 导出表的结构
exp userid=scott/tiger@accp tables=(emp) file=d:\e3.dmp rows=n
4. 使用直接导出方式
exp userid=scott/tiger@accp tables=(emp) file=d:\e4.dmp direct=y
这种方式比默认的常规方式速度要快,当数据量大时,可以考虑使用这样的方法。
这时需要数据库的字符集要与客户端字符集完全一致,否则会报错...
导出方案.
导出方案是指使用export工具导出一个方案或是多个方案中的所有对象(表,索引,约束...)和数据。并存放到文件中。
1. 导出自己的方案
exp userid=scott/tiger@myorcl owner=scott file=d:\scott.dmp
2. 导出其它方案
如果用户要导出其它方案,则需要dba的权限或是exp_full_database的权限,
比如system用户就可以导出任何方案
exp userid=system/manager@myorcl owner=(system,scott)
file=d:\system.dmp
. 导出数据库
导出数据库是指利用export导出所有数据库中的对象及数据,要求该用户具有dba的权限或者是exp_full_database权限
增量备份(好处是第一次备份后,第二次备份就快很多了)
exp userid=system/manager@myorcl full=y inctype=complete
file=d:\all.dmp
导入
导入就是使用工具import将文件中的对象和数据导入到数据库中,但是导入要使用的文件必须是export所导出的文件。与导出相似,导入也分为导入表,导入方案,导入数据库三种方式。
imp常用的选项有
userid: 用于指定执行导入操作的用户名,口令,连接字符串
tables: 用于指定执行导入操作的表
formuser: 用于指定源用户
touser: 用于指定目标用户 file: 用于指定导入文件名
full=y: 用于指定执行导入整个文件
inctype: 用于指定执行导入操作的增量类型
rows: 指定是否要导入表行(数据)
ignore: 如果表存在,则只导入数据
导入表.
1. 导入自己的表
imp userid=scott/tiger@myorcl tables=(emp) file=d:\xx.dmp
2. 导入表到其它用户
要求该用户具有dba的权限,或是imp_full_database
imp userid=system/tiger@myorcl tables=(emp) file=d:\xx.dmp touser=scott
3. 导入表的结构
只导入表的结构而不导入数据
imp userid=scott/tiger@myorcl tables=(emp) file=d:\xx.dmp rows=n
4. 导入数据
如果对象(如比表)已经存在可以只导入表的数据
imp userid=scott/tiger@myorcl tables=(emp) file=d:\xx.dmp ignore=y
导入方案.
导入方案是指使用import工具将文件中的对象和数据导入到一个或是多个方案中。如果要导入其它方案,要求该用户具有dba的权限,或者imp_full_database
1. 导入自身的方案
imp userid=scott/tiger file=d:\xxx.dmp
2. 导入其它方案
要求该用户具有dba的权限
imp userid=system/manager file=d:\xxx.dmp fromuser=system touser=scott
导入数据库.
在默认情况下,当导入数据库时,会导入所有对象结构和数据,案例如下:
imp userid=system/manager full=y file=d:\xxx.dmp
11.数据字典和动态性能视图
介绍
数据字典是oracle数据库中最重要的组成部分,它提供了数据库的一些系统信息。
动态性能视图记载了例程启动后的相关信息。
.数据字典
数据字典记录了数据库的系统信息,它是只读表和视图的集合,数据字典的所有者为sys用户。
用户只能在数据字典上执行查询操作(select语句),而其维护和修改是由系统自动完成的。
这里我们谈谈数据字典的组成:数据字典包括数据字典基表和数据字典视图,其中基表存储数据库的基本信息,普通用户不能直接访问数据字典的基表。数据字典视图是基于数据字典基表所建立的视图,普通用户可以通过查询数据字典视图取得系统信息。数据字典视图主要包括user_xxx,all_xxx,dba_xxx三种类型。
user_tables;.
用于显示当前用户所拥有的所有表,它只返回用户所对应方案的所有表
比如:select table_name from user_tables;
all_tables;.
用于显示当前用户可以访问的所有表,它不仅会返回当前用户方案的所有表,还会返回当前用户可以访问的其它方案的表: 比如:select table_name from all_tables;
dba_tables;.
它会显示所有方案拥有的数据库表。但是查询这种数据库字典视图,要求用户必须是dba角色或是有select any table系统权限。 例如:当用system用户查询数据字典视图dba_tables时,会返回system,sys,scott...方案所对应的数据库表。
. 用户名,权限,角色
在建立用户时,oracle会把用户的信息存放到数据字典中,当给用户授予权限
或是角色时,oracle会将权限和角色的信息存放到数据字典。
通过查询dba_users可以显示所有数据库用户的详细信息;
通过查询数据字典视图dba_sys_privs,可以显示用户所具有的系统权限;
通过查询数据字典视图dba_tab_privs,可以显示用户具有的对象权限;
通过查询数据字典dba_col_privs可以显示用户具有的列权限;
通过查询数据库字典视图dba_role_privs可以显示用户所具有的角色。
这里给大家再讲讲角色和权限的关系。
例如:要查看scott具有的角色,可查询dba_role_privs;
SQL> select * from dba_role_privs where grantee='SCOTT';
//查询orale中所有的系统权限,一般是dba
select * from system_privilege_map order by name;
//查询oracle中所有对象权限,一般是dba
select distinct privilege from dba_tab_privs;
//查询oracle中所有的角色,一般是dba
select * from dba_roles;
//查询数据库的表空间
select tablespace_name from dba_tablespaces;
问题1:如何查询一个角色包括的权限?
a.一个角色包含的系统权限
select * from dba_sys_privs where grantee='角色名'
另外也可以这样查看:
select * from role_sys_privs where role='角色名'
b.一个角色包含的对象权限
select * from dba_tab_privs where grantee='角色名'
问题2:oracle究竟有多少种角色?
SQL> select * from dba_roles;
问题3:如何查看某个用户,具有什么样的角色?
select * from dba_role_privs where grantee='用户名'
显示当前用户可以访问的所有数据字典视图。.
select * from dict where comments like '%grant%';
显示当前数据库的全称.
select * from global_name;
其它说明.
数据字典记录有oracle数据库的所有系统信息。通过查询数据字典可以取得以下系统信息:如
1.对象定义情况
2.对象占用空间大小 3.列信息
4.约束信息 ...
但是因为这些个信息,可以通过pl/sql developer工具查询得到,所以这里我就飘过。
.动态性能视图
动态性能视图用于记录当前例程的活动信息,当启动oracle server时,系统会建立动态性能视图;当停止oracle server时,系统会删除动态性能视图。oracle的所有动态性能视图都是以v_$开始的,并且 oracle为每个动态性能视图都提供了相应的同义词,并且其同义词是以V$开始的,例如v_$datafile的同义词为v$datafile;动态性能视图的所有者为sys,一般情况下,由dba或是特权用户来查询动态性能视图。 因为这个在实际中用的较少,所以飞过。
12.数据库管理 -- 管理表空间和数据文件
介绍.
表空间是数据库的逻辑组成部分。从物理上讲,数据库数据存放在数据文件中;从逻辑上讲,数据库则是存放在表空间中,表空间由一个或多个数据文件组成。
数据库的逻辑结构
oracle中逻辑结构包括表空间、段、区和块。
说明一下数据库由表空间构成,而表空间又是由段构成,而段又是由区构成,而区又是由oracl块构成的这样的一种结构,可以提高数据库的效率。
表空间
表空间用于从逻辑上组织数据库的数据。数据库逻辑上是由一个或是多个表空间组成的。通过表空间可以达到以下作用:
1. 控制数据库占用的磁盘空间
2. dba可以将不同数据类型部署到不同的位置,这样有利于提高i/o性能,同时利于备份和恢复等管理操作。
建立表空间.
建立表空间是使用crate tablespace命令完成的,需要注意的是,一般情况下,
建立表空间是特权用户或是dba来执行的,如果用其它用户来创建表空间,则用户必须要具有create tablespace的系统权限。
建立数据表空间.
在建立数据库后,为便于管理表,最好建立自己的表空间
create tablespace data01 datafile 'd:\test\dada01.dbf' size 20m uniform size 128k;
说明:执行完上述命令后,会建立名称为data01的表空间,并为该表空间建立名称为data01.dbf的数据文件,区的大小为128k
. 使用数据表空间
create table mypart(deptno number(4), dname varchar2(14), loc varchar2(13)) tablespace data01;
改变表空间的状态.
当建立表空间时,表空间处于联机的(online)状态,此时该表空间是可以访问的,并且该表空间是可以读写的,即可以查询该表空间的数据,而且还可以在表空间执行各种语句。但是在进行系统维护或是数据维护时,可能需要改变表空间的状态。一般情况下,由特权用户或是dba来操作。
1. 使表空间脱机
alter tablespace 表空间名 offline;
2. 使表空间联机
alter tablespace 表空间名 online;
3. 只读表空间
当建立表空间时,表空间可以读写,如果不希望在该表空间上执行update,delete,insert操作,那么可以将表空间修改为只读 alter tablespace 表空间名 read only;
(修改为可写是 alter tablespace 表空间名 read write;)
改变表空间的状态.
我们给大家举一个实例,说明只读特性:
1. 知道表空间名,显示该表空间包括的所有表
select * from all_tables where tablespace_name=’表空间名’;
2. 知道表名,查看该表属于那个表空间
select tablespace_name, table_name from user_tables where table_name=’emp’;
通过2.我们可以知道scott.emp是在system这个表空间上,现在我们可以将system改为只读的但是我们不会成功,因为system是系统表空间,如果是普通表空间,那么我们就可以将其设为只读的,给大家做一个演示,可以加强理解。
3. 使表空间可读写 alter tablespace 表空间名 read write;
. 删除表空间
一般情况下,由特权用户或是dba来操作,如果是其它用户操作,那么要求用户具有drop tablespace系统权限。
drop tablespace ‘表空间’ including contents and datafiles;
说明:including contents表示删除表空间时,删除该空间的所有数据库对象,而datafiles表示将数据库文件也删除。
扩展表空间.
表空间是由数据文件组成的,表空间的大小实际上就是数据文件相加后的大小。那么我们可以想象,假定表employee存放到data01表空间上,初始大小就是2M,当数据满2M空间后,如果在向employee表插入数据,这样就会显示空间不足的错误。
案例说明:
1. 建立一个表空间 sp01
2. 在该表空间上建立一个普通表 mydment 其结构和dept一样
3. 向该表中加入数据 insert into mydment select * from dept;
4. 当一定时候就会出现无法扩展的问题,怎么办?
5. 就扩展该表空间,为其增加更多的存储空间。有三种方法:
1. 增加数据文件
SQL> alter tablespace sp01 add datafile ‘d:\test\sp01.dbf’ size 20m;
2. 增加数据文件的大小
SQL> alter tablespace 表空间名 ‘d:\test\sp01.dbf’ resize 20m;
这里需要注意的是数据文件的大小不要超过500m。
3. 设置文件的自动增长。
SQL> alter tablespace 表空间名 ‘d:\test\sp01.dbf’ autoextend on next 10m maxsize 500m;
移动数据文件.
有时,如果你的数据文件所在的磁盘损坏时,该数据文件将不能再使用,为了能够重新使用,需要将这些文件的副本移动到其它的磁盘,然后恢复。
下面以移动数据文件sp01.dbf为例来说明:
1. 确定数据文件所在的表空间
select tablespace_name from dba_data_files where file_name=’d:\test\sp01.dbf’;
2. 使表空间脱机
确保数据文件的一致性,将表空间转变为offline的状态。
alter tablespace sp01(表空间名) offline;
3. 使用命令移动数据文件到指定的目标位置
host move d:\test\sp01.dbf c:\test\sp01.dbf
4. 执行alter tablespace命令
在物理上移动了数据后,还必须执行alter tablespace命令对数据库文件进行逻辑修改:
alter tablespace sp01 rename datafile ‘d:\test\sp01.dbf’ to ‘c:\test\sp01.dbf’;
5. 使得表空间联机
在移动了数据文件后,为了使用户可以访问该表空间,必须将其转变为online状态。
alter tablespace sp01(表空间名) online;
显示表空间信息.
查询数据字典视图dba_tablespaces,显示表空间的信息:
select tablespace_name from dba_tablespaces;
显示表空间所包含的数据文件.
查询数据字典视图dba_data_files,可显示表空间所包含的数据文件,如下:
select file_name, bytes from dba_data_files where tablespce_name=’表空间’;
表空间小结.
1. 了解表空间和数据文件的作用
2. 掌握常用表空间,undo表空间和临时表空间的建立方法
3. 了解表空间的各个状态(online, offline, read write, read only)的作用,及如何改变表空间的状态的方法。
4. 了解移动数据文件的原因,及使用alter tablespace 和alter datatable命令移动数据文件的方法。
其它表空间.
除了最常用的数据表空间外,还有其它类型表空间:
1. 索引表空间
2. undo表空间 3. 临时表空间
4. 非标准块的表空间
13.约束
介绍.
数据的完整性用于确保数据库数据遵从一定的商业和逻辑规则,在oracle中,
数据完整性可以使用约束、触发器、应用程序(过程、函数)三种方法来实现,
在这三种方法中,因为约束易于维护,并且具有最好的性能,所以作为维护数据
完整性的首选。
约束.
约束用于确保数据库数据满足特定的商业规则。在oracle中,约束包括:not null、 unique, primary key, foreign key,和check五种。
使用
not null(非空).如果在列上定义了not null,那么当插入数据时,必须为列提供数据。
unique(唯一).当定义了唯一约束后,该列值是不能重复的,但是可以为null。
primary key(主键).
用于唯一的标示表行的数据,当定义主键约束后,该列不但不能重复而且不能为null。
需要说明的是:一张表最多只能有一个主键,但是可以有多个unqiue约束。
foreign key(外键).
用于定义主表和从表之间的关系。外键约束要定义在从表上,主表则必须具有主键约束或是unique约束,当定义外键约束后,要求外键列数据必须在主表的主键列存在或是为null。
check.
用于强制行数据必须满足的条件,假定在sal列上定义了check约束,并要求sal列值在1000-2000之间如果不在1000-2000之间就会提示出错。
商店售货系统表设计案例.
现有一个商店的数据库,记录客户及其购物情况,由下面三个表组成:商品goods(商品号goodsId,商品名 goodsName,单价 unitprice,商品类别category,供应商provider);
客户customer(客户号customerId,姓名name,住在address,电邮email,
性别sex,×××cardId);
购买purchase(客户号customerId,商品号goodsId,购买数量nums);
请用SQL语言完成下列功能:
1. 建表,在定义中要求声明:
(1). 每个表的主外键;
(2). 客户的姓名不能为空值;
(3). 单价必须大于0,购买数量必须在1到30之间;
(4). 电邮不能够重复;
(5). 客户的性别必须是 男 或者 女,默认是男;
SQL> create table goods(goodsId char(8) primary key, --主键
goodsName varchar2(30),
unitprice number(10,2) check(unitprice>0),
category varchar2(8),
provider varchar2(30) );
SQL> create table customer( customerId char(8) primary key, --主键
name varchar2(50) not null, --不为空
address varchar2(50),
email varchar2(50) unique,
sex char(2) default '男' check(sex in ('男','女')),
-- 一个char能存半个汉字,两位char能存一个汉字 cardId char(18) );
SQL> create table purchase( customerId char(8) references
customer(customerId),
goodsId char(8) references goods(goodsId),
nums number(10) check (nums between 1 and 30) );
表是默认建在SYSTEM表空间的
维护
商店售货系统表设计案例(2).
如果在建表时忘记建立必要的约束,则可以在建表后使用alter table命令为表
增加约束。但是要注意:增加not null约束时,需要使用modify选项,而增加
其它四种约束使用add选项。
1. 增加商品名也不能为空 SQL> alter table goods modify goodsName not null;
2. 增加×××也不能重复 SQL> alter table customer add constraint xxxxxx unique(cardId);
3. 增加客户的住址只能是’海淀’,’朝阳’,’东城’,’西城’,’通州’,’崇文’,’昌平’;
SQL> alter table customer add constraint yyyyyy check (address in (’ 海淀’,’朝阳’,’东城’,’西城’,’通州’,’崇文’,’昌平’));
删除约束.
当不再需要某个约束时,可以删除。
alter table 表名 drop constraint 约束名称;
特别说明一下: 在删除主键约束的时候,可能有错误,比如: alter table 表名 drop primary key;
这是因为如果在两张表存在主从关系,那么在删除主表的主键约束时,必须带上cascade选项 如像: alter table 表名 drop primary key cascade;
显示约束信息.
1.显示约束信息
通过查询数据字典视图user_constraints,可以显示当前用户所有的约束的信息。
select constraint_name, constraint_type, status, validated from user_constraints where table_name = '表名';
2.显示约束列
通过查询数据字典视图user_cons_columns,可以显示约束所对应的表列信息。
select column_name, position from user_cons_columns where constraint_name = '约束名';
3.当然也有更容易的方法,直接用pl/sql developer查看即可。简单演示一下下...
表级定义 列级定义
列级定义.
列级定义是在定义列的同时定义约束。
如果在department表定义主键约束
create table department4(dept_id number(12) constraint pk_department primary key, name varchar2(12), loc varchar2(12));
表级定义.
表级定义是指在定义了所有列后,再定义约束。这需要注意: not null约束只能在列级上定义。
以在建立employee2表时定义主键约束和外键约束为例:
create table employee2(emp_id number(4), name varchar2(15), dept_id number(2), constraint pk_employee primary key (emp_id), constraint fk_department foreign key (dept_id) references department4(dept_id));
14.Oracle索引、权限
介绍.
索引是用于加速数据存取的数据对象。合理的使用索引可以大大降低i/o次数,从而提高数据访问性能。索引有很多种我们主要介绍常用的几种:
为什么添加了索引后,会加快查询速度呢?
创建索引
单列索引是基于单个列所建立的索引,比如: create index 索引名 on 表名(列名);
复合索引是基于两列或是多列的索引。在同一张表上可以有多个索引,但是要求列的组合必须不同,比如: create index emp_idx1 on emp (ename, job);
create index emp_idx1 on emp (job, ename);
使用原则.
1. 在大表上建立索引才有意义
3. 索引的层次不要超过4层 2. 在where子句或是连接条件上经常引用的列上建立索引
索引有一些先天不足:
1. 建立索引,系统要占用大约为表1.2倍的硬盘和内存空间来保存索引。
2. 更新数据的时候,系统必须要有额外的时间来同时对索引进行更新,以维持数据和索引的一致性。
实践表明,不恰当的索引不但于事无补,反而会降低系统性能。因为大量的索引在进行插入、修改和删除操作时比没有索引花费更多的系统时间。
比如在如下字段建立索引应该是不恰当的:
1. 很少或从不引用的字段; 2. 逻辑型的字段,如男或女(是或否)等。
综上所述,提高查询效率是以消耗一定的系统资源为代价的,索引不能盲目的建立,这是考验一个DBA是否优秀的很重要的指标。
其它索引
介绍.
按照数据存储方式,可以分为B*树、反向索引、位图索引;
按照索引列的个数分类,可以分为单列索引、复合索引;
按照索引列值的唯一性,可以分为唯一索引和非唯一索引。
此外还有函数索引,全局索引,分区索引...
对于索引我还要说:
在不同的情况,我们会在不同的列上建立索引,甚至建立不同种类的索引,请记住,技术是死的,人是活的。比如:
B*树索引建立在重复值很少的列上,而位图索引则建立在重复值很多、不同值相对固定的列上。
显示索引信息
. 显示表的所有索引
在同一张表上可以有多个索引,通过查询数据字典视图dba_indexs和user_indexs,可以显示索引信息。其中dba_indexs用于显示数据库所有的索引信息,而user_indexs用于显示当前用户的索引信息: select index_name, index_type from user_indexes where table_name = '表名';
显示索引列.
通过查询数据字典视图user_ind_columns,可以显示索引对应的列的信息
select table_name, column_name from user_ind_columns where index_name = 'IND_ENAME';
. 你也可以通过pl/sql developer工具查看索引信息
管理权限和角色
这一部分我们主要看看oracle中如何管理权限和角色,权限和角色的区别在那里。
当刚刚建立用户时,用户没有任何权限,也不能执行任何操作。如果要执行某种特定的数据库操作,则必须为其授予系统的权限;如果用户要访问其它方案的对象,则必须为其授予对象的权限。为了简化权限的管理,可以使用角色。
权限是指执行特定类型sql命令或是访问其它方案对象的权利,包括系统权限和对象权限两种。
系统权限是指执行特定类型sql命令的权利。它用于控制用户可以执行的一个或是一组数据库操作。比如当用户具有create table权限时,可以在其方案中建表,当用户具有create any table权限时,可以在任何方案中建表。oracle提供了 100多种系统权限。
常用的有:
create session 连接数据库
create table 建表
create view 建视图
create public synonym 建同义词 create procedure 建过程、函数、包
create trigger 建触发器
create cluster 建簇