函数库查询:
http://download-west.oracle.com/docs/cd/B10501_01/server.920/a96540/functions2a.htm#80856
//连接sqlplus
sqlplus system/storystory@localhost
//网页链接sqlplus http://192.168.1.101:5560/isqlplus/
//后台管理
http://forever:1158/em/
//对账号解锁
//统计表个数
select owner,count(*) from all_tables group by owner;
1.创建表空间
CREATE TABLESPACE CRM
DATAFILE 'C:\oracle\product\10.2.0\oradata\story\CRM.ORA'
SIZE 5M;
//查看表空间信息
SELECT c.tablespace_name tablespace_name, ROUND(a.bytes/1048576,2) total_size,ROUND((a.bytes-b.bytes)/1048576,2) used_size,
ROUND(b.bytes/1048576,2) free_size,
ROUND(b.bytes/a.bytes * 100,2)||'%' free_pct FROM
(SELECT tablespace_name,SUM(a.bytes) bytes
FROM sys.DBA_DATA_FILES a
GROUP BY tablespace_name) a,
(SELECT a.tablespace_name,
NVL(SUM(b.bytes),0) bytes
FROM sys.DBA_DATA_FILES a,
sys.DBA_FREE_SPACE b
WHERE a.tablespace_name = b.tablespace_name (+)
AND a.file_id = b.file_id (+)
GROUP BY a.tablespace_name) b,
sys.DBA_TABLESPACES c
WHERE a.tablespace_name = b.tablespace_name(+)
AND a.tablespace_name = c.tablespace_name
ORDER BY ROUND(b.bytes/1048576,2);
//删除表空间
1.首先看一下是不是已经使用了OMF
sql>show parameter db_create
查看参数db_create_file_dest,如果已经设置
则:drop tablespace tablespacename 就可以直接删除表空间以及相应的数据文件
2.如果没使用OMF,则:
drop tablespace tablespacename including contents and datafiles
//查看指定用户的表
SELECT TABLE_NAME FROM USER_TABLES;
//修改用户表名字
ALTER TABLE BOOK_INFO RENAME TO BOOKS;
//查看表字段
DESCRIBE DEPART;
//修改表字段名字
ALTER TABLE EMP RENAME COLUMN EMP_TEL TO EMP_TELS;
ALTER TABLE 表名 RENAME COLUMN 旧字段 TO 新字段;
//修改表字段的类型
ALTER TABLE EMP MODIFY EMP_SEX VARCHAR2(20);
//修改表名
ALTER TABLE EMPS RENAME TO EMP;
//添加新字段
ALTER TABLE EMP ADD HEAD VARCHAR2(10);
//删除表字段
ALTER TABLE EMP DROP COLUMN HEAD;
//复制表
CREATE TABLE EMPS AS SELECT * FROM EMP;
2.创建用户
CREATE USER FOREVER
IDENTIFIED BY FOREVER
DEFAULT TABLESPACE CRM;
//查看当前的所有用户信息
SELECT * FROM ALL_USERS;
//删除指定用户
DROP USER USER_NAME CASCADE;
3.给用户授权
GRANT CONNECT TO FOREVER;
GRANT RESOURCE TO FOREVER;
4.// 当前用户断开服务器
DISCONNECT;
5.//重新连接用户forever
CONNECT FOREVER/FOREVER;
6.//创建表
CREATE TABLE DEPART
(
DEPART_ID INT PRIMARY KEY,
DEPART_NAME VARCHAR2(32),
CREATE_TIME DATE,
REMARK VARCHAR2(128)
);
CREATE TABLE EMP
(
EMP_ID INT PRIMARY KEY,
DEPART_ID INT REFERENCES DEPART(DEPART_ID),
EMP_NAME VARCHAR2(16),
EMP_SEX CHAR(2),
EMP_TEL VARCHAR2(32)
);
//查看表结构
看字段名与数据类型
select * from cols WHERE TABLE_name=upper('table_name')
查看主键:
select * from user_constraints where constraint_type='P'
and TABLE_name=upper('table_name')
//创建序列:
//为每张表做序列,自增
CREATE SEQUENCE SEQ_DEPART_ID;
CREATE SEQUENCE SEQ_EMP_ID;
//查看序列的下一个值和下一个值。
SELECT SEQ_DEPART_ID.NEXTVAL FROM DUAL;
SELECT SEQ_DEPART_ID.CURRVAL FROM DUAL;
//添加测试数据
INSERT INTO DEPART VALUES (1,'人事部',SYSDATE,'2012年');
INSERT INTO DEPART VALUES (2,'市场部',SYSDATE,'2012年');
INSERT INTO DEPART VALUES (3,'财务部',SYSDATE,'2012年');
INSERT INTO DEPART VALUES (4,'开发部',SYSDATE,'2012年');
INSERT INTO DEPART VALUES (5,'销售部',SYSDATE,'2012年');
INSERT INTO EMP VALUES(2,1,'CHENJUN2','男','88888888');
INSERT INTO EMP VALUES(3,1,'CHENJUN3','男','88888888');
INSERT INTO EMP VALUES(4,1,'CHENJUN4','男','88888888');
INSERT INTO EMP VALUES(5,1,'CHENJUN5','男','88888888');
INSERT INTO EMP VALUES(6,1,'CHENJUN6','男','88888888');
INSERT INTO EMP VALUES(7,1,'CHENJUN7','男','88888888');
INSERT INTO EMP VALUES(8,1,'CHENJUN8','男','88888888');
INSERT INTO EMP VALUES(9,1,'CHENJUN9','男','88888888');
INSERT INTO EMP VALUES(10,1,'CHENJUN10','男','88888888');
INSERT INTO EMP VALUES(11,1,'CHENJUN11','男','88888888');
INSERT INTO EMP VALUES(12,1,'CHENJUN12','男','88888888');
INSERT INTO EMP VALUES(13,1,'CHENJUN13','男','88888888');
INSERT INTO EMP VALUES(14,1,'CHENJUN14','男','88888888');
INSERT INTO EMP VALUES(15,1,'CHENJUN15','男','88888888');
INSERT INTO EMP VALUES(16,1,'CHENJUN16','男','88888888');
INSERT INTO EMP VALUES(17,1,'CHENJUN17','男','88888888');
INSERT INTO EMP VALUES(18,1,'CHENJUN18','男','88888888');
INSERT INTO EMP VALUES(19,1,'CHENJUN19','男','88888888');
INSERT INTO EMP VALUES(20,1,'CHENJUN20','男','88888888');
INSERT INTO EMP VALUES(21,1,'CHENJUN21','男','88888888');
INSERT INTO EMP VALUES(22,1,'CHENJUN22','男','88888888');
//所有的部门的人员信息
SELECT DEPART.DEPART_ID,DEPART.DEPART_NAME,EMP.EMP_NAME,EMP_SEX,EMP_TEL FROM DEPART
LEFT JOIN EMP
ON DEPART.DEPART_ID=EMP.DEPART_ID;
//统计
SELECT COUNT(*) FROM DEPART
LEFT JOIN EMP
ON DEPART.DEPART_ID=EMP.DEPART_ID;
//rowid
SELECT ROWID ,ROWNUM......
//分页语句
SELECT MAX(ROWNUM) FROM
(SELECT ROWNUM FROM EMP WHERE ROWNUM<6);
------------------
SELECT * FROM
(SELECT ROWNUM AS NUM,EMP.* FROM EMP WHERE ROWNUM <=(页号)*页大小)
IEMP WHERE IEMP.NUM>(页号-1)*页大小;
LPAD(字段,长度,补充)数据补充
1_1
1_2
1_3
1_4
1_5
1_6
1_7
1_8
1_9
1_10
对以上进行排序操作
统计每个部门下面有多少员工
//对表进行加锁
//对每个分区进行备份
分区方法
范围分区
分区维护
查询分区
删除分区
截断分区
合并相邻的分区
拆分分区
查看一张表分区
序列操作
解锁操作
ALTER USER scott ACCOUNT UNLOCK;
-------------------分割线------------------------------
oracle的一些命令:
set linesize 300; 设置行大小
set pagesize 30; 设置页(重复出现的标题)
select * from tab; 表示查询出当前数据库中使用的所有表
show user; 显示当时是哪个用户在登录
conn scott/tiger 转换成另scott用户来登录
conn sys/admin as sysdba 转换成系统管理员登录的方式
字符函数:
SELECT UPPER('smith')FROM DUAL; 转换成大写
SELECT LOWER('SMITH')FROM DUAL; 转换成小写
SELECT SUBSTR('HELLO',1,3)FROM DUAL; 截取字符串的长度(从1开始截取3个)
oracle中截取字符串是从0或1开始截取是没有区别的
SELECT LENGTH('HELLOWORD')FROM DUAL; 表示获得当前字符串的长度
SELECT REPLACE('HELLO','L','X')FROM DUAL; 表示替换字符
数字函数:
SELECT ROUND(182.165)FROM DUAL; 表示四舍五入的函数
SELECT TRUNC(789.125,-2)FROM DUAL; 表示进位函数
SELECT MOD(10,3)FROM DUAL; 表示求余函数
日期函数(oracle中的日期函数有一些规律)
日期-数字=日期
日期+数字=日期
日期-日期=数字(天数)
当前日期:SELECT SYSDATE FROM DUAL;
MONTHS_BETWEEN() 求出给定日期范围的月数
ADD_MONTHS() 在指定日期上加上指定的月数,求出之后的日期
NEXT_DAY() 下一个今天是那一个日期
LAST_DAY() 求出给定日期的最后一天日期
转换函数:
TO_CHAR:转换成字符串 SELECT TO_CHAR(SYSDATE,'FMYYYY-MM-DD')FROM DUAL;
TO_NUMBER:转换成数字 SELECT TO_NUMBER('123')+TO_NUMBER('25')FRON DUAL;
TO_DATE:转换成日期 SELECT TO_DATE('2009-02-16','YYYY-MM-DD')FROM DUAL;
NVL函数:可以将一个指定的null值变为指定的内容
SELECT EMPNO,ENAME,NVL(COMM,0)FROM EMP
DECODE函数:相当于多从if...elseif...elseif..else
SELECT DECODE(1,1,'内容是1',2,'内容是2',3,'内容是3')FROM DUAL;
分组函数:
group by
having
1.如果程序中使用咯分组函数,则有两种可以使用使用情况:
a.程序中存在了group by,并指定了分组条件,这样可以将分组条件一起查询出来
right:SELECT DEPTNO,MAX(SAL) FROM EMP GROUP BY DEPTNO;
wrong:SELECT DEPTNO,MIX(SAL) FROM EMP;
b.如果不使用分组的话,则只能单独的使用分组函数
right:SELECT COUNT(EMPNO) FROM EMP;
wrong: SELECT ENAME,SUM(SAL) FROM EMP;
2.在使用了分组函数的时候,不能出现分组函数和分组条件之外的字段.
right:SELECT DEPTNO,COUNT(EMPNO) FROM EMP GROUP BY DEPTNO;
wrong:SELECT DEPTNO,ENAME,MAX(SAL) FROM EMP GROUP BY DEPTNO;
3.分组函数只能在分组中使用,不允许在where语句之中出现,那么如果现在要指定分组的条件,则只能通过having指定来完成
right:SELECT DEPTNO,AVG(SAL)FROM EMP GROUP BY DEPTNO HAVING AVG(SAL)>2000
wrong:SELECT DEPTNO,AVG(SAL)FROM EMP WHERE AVG(SAL)>2000 GROUP BY DEPTNO;
4.分组函数允许嵌套,但是嵌套之后就不能在查询其他的字段,包括分组字段
right:SELECT MAX(AVG(SAL)) FROM EMP GROUP BY DEPTNO;
wrong:SELECT deptno,MAX(AVG(SAL)) FROM EMP GROUP BY DEPTNO;
事物处理:所谓的事物处理就是保证数据操作的完整性,所有的操作要么同时成功,要么同时失败,在oracle中对于每一个连接到数据库窗口(sqlplus,sqlplusw)连接之后实际上都会与数据库的连接建立一个
session,即:每一个连接到数据库上的用户都表示创建了一个session(会话)
一个session对数据库所做的修改,不会立即反映到数据库上真实数据之上,是允许回滚的,当一个session提交所有的操作之后,数据库才真正的做出修改。
在数据库的操作中提供了以下两个主要命令完成事物的处理:
* 提交事物:commit
* 回滚事物:rollback
如果数据被提交了,肯定是不能在回滚的咯哦。
注意:在oracle中关于事物的处理上也会存在一种死锁的概念
一个session如果跟新了数据库中的记录,其他的session是无法立刻跟新的,要等待对方提交之后才允许跟新。
//查询所有员工,在哪个部门,拿多少工资,以及工资等级(3张表级联查询)
SELECT E.ENAME,E.SAL,DNAME,S.GRADE
FROM EMP E,DEPT D,SALGRADE S
WHERE E.DEPTNO=D.DEPTNO AND E.SAL BETWEEN S.LOSAL AND S.HISAL;
//查询所有员工,在哪个部门,拿多少工资,以及工资等级?在把所有经理的姓名,工资,工资等级查询出来(5张表级联查询)
SELECT E.ENAME,E.SAL,DNAME,S.GRADE,M.ENAME,M.SAL,MS.GRADE
FROM EMP E,DEPT D,SALGRADE S,EMP M,SALGRADE MS
WHERE E.DEPTNO=D.DEPTNO AND E.SAL BETWEEN S.LOSAL AND S.HISAL AND E.MGR=M.EMPNO AND M.SAL
BETWEEN MS.LOSAL AND MS.HISAL;
//按工资等级来查询
SELECT E.ENAME,E.SAL,D.DNAME,
DECODE(S.GRADE,1,'第五等工资',2,'第四等工资',3,'第三等工资'
,4,'第二等工资',5,'第一等工资'),M.ENAME,M.SAL,
DECODE(MS.GRADE,1,'第五等工资',2,'第四等工资',3,'第三等工资'
,4,'第二等工资',5,'第一等工资')
FROM EMP E,DEPT D,SALGRADE S,EMP M,SALGRADE MS
WHERE E.DEPTNO=D.DEPTNO AND E.SAL BETWEEN S.LOSAL AND S.HISAL AND E.MGR=M.EMPNO AND M.SAL BETWEEN MS.LOSAL AND MS.HISAL;
//左右连接
//(+)在=右边表示左连接
SELECT E.EMPNO,E.ENAME,D.DEPTNO,D.DNAME,D.LOC
FROM EMP E,DEPT D
WHERE E.DEPTNO=D.DEPTNO(+)
相等于 LEFE OUTER JOIN
SELECT E.EMPNO,E.ENAME,D.DNAME
FROM EMP E LEFT JOIN DEPT D ON(E.DEPTNO=D.DEPTNO)
//(+)在=左边表示右连接
SELECT E.EMPNO,E.ENAME,D.DEPTNO,D.DNAME,D.LOC
FROM EMP E,DEPT D
WHERE E.DEPTNO(+)=D.DEPTNO
相当于RIGHT OUTER JOIN
SELECT E.EMPNO,E.ENAME,D.DNAME
FROM EMP E RIGHT JOIN DEPT D ON(E.DEPTNO=D.DEPTNO)
//查询所有员工姓名,编号,经理编号,姓名
SELECT E.EMPNO,E.ENAME,M.ENAME,M.EMPNO
FROM EMP E,EMP M
WHERE E.MGR=M.EMPNO(+)
//交叉连接(产生了笛卡尔积)
SELECT * FROM EMP CROSS JOIN DEPT;
//自然连接(自动进行关联字段的匹配)
SELECT * FROM EMP NATURAL JOIN DEPT;
//USING()字句直接关联操作列
SELECT * FROM EMP E JOIN DEPT D USING(DEPTNO) WHERE DEPTNO=20;
//ON()表示拥护自己编写连接条件
SELECT * FROM EMP E JOIN DEPT D ON(E.DEPTNO=D.DEPTNO) WHERE E.DEPTNO=20;
1.列出最低薪金大于1500的各种工作及从事此工作的全部雇员人数。
a.按工作分组,分组条件最低工资低于1500。
SELECT JOB,MIN(SAL)
FROM EMP
GROUP BY JOB HAVING MIN(SAL)>1500
b.工资已经求来了,之后再求全部的雇员人数。
SELECT E.JOB,COUNT(E.EMPNO)
FROM EMP E
WHERE E.JOB IN(
SELECT JOB
FROM EMP
GROUP BY JOB HAVING MIN(SAL)>1500)
GROUP BY E.JOB
2.列出在部门"SALES"(销售部)工作的员工的姓名,假定不知道销售部的部门编号。
a.通过dept表查询出销售部的部门编号
SELECT DEPTNO FROM DEPT WHERE DNAME='SALES'
b.将之前的查询作为子查询:
SELECT ENAME FROM EMP WHERE DEPTNO=(SELECT DEPTNO FROM DEPT WHERE DNAME='SALES')
3.列出薪金高于公司平均薪金的所有员工,所在部门,上级领导,公司的工资等级。
a.求出公司的平均工资
SELECT AVG(SAL) FROM EMP
b.列出薪金高于平均工资的所有雇员信息
SELECT * FROM EMP WHERE SAL>(SELECT AVG(SAL) FROM EMP)
C.与部门表关联,查询出所在部门的信息
SELECT E.*,D.LOC
FROM EMP E,DEPT D
WHERE SAL>(SELECT AVG(SAL) FROM EMP) AND E.DEPTNO=D.DEPTNO
d.要想查询出上级领导,要与自身关联
SELECT E.EMPNO,E.ENAME,M.EMPNO,M.ENAME,D.DEPTNO,D.LOC
FROM EMP E,DEPT D,EMP M
WHERE E.SAL>(SELECT AVG(SAL) FROM EMP)
AND E.DEPTNO=D.DEPTNO AND E.MGR=M.EMPNO(+)
e.求出雇员的工资等级
SELECT E.EMPNO,E.ENAME,S.GRADE,M.EMPNO,M.ENAME,D.DEPTNO,D.LOC
FROM EMP E,DEPT D,EMP M,SALGRADE S
WHERE E.SAL>(SELECT AVG(SAL) FROM EMP)
AND E.DEPTNO=D.DEPTNO AND E.MGR=M.EMPNO(+)
AND E.SAL BETWEEN S.LOSAL AND S.HISAL
4.列出soctt从事相同工作的所有员工及部门名称
a.找出scott的工作
SELECT JOB FROM EMP WHERE ENAME='SCOTT'
b.找出与其相同的雇员
SELECT EMPNO,ENAME,JOB,SAL FROM EMP WHERE JOB=(SELECT JOB FROM EMP WHERE ENAME='SCOTT')
c.以上结果中存在scott,实际上现在不应该出现scott
SELECT EMPNO,ENAME,JOB,SAL FROM EMP WHERE JOB=(SELECT JOB FROM EMP WHERE ENAME='SCOTT') AND ENAME!='SCOTT'
d.在求出部门名称
SELECT E.EMPNO,E.ENAME,E.JOB,E.SAL,D.DNAME,D.LOC
FROM EMP E,DEPT D
WHERE JOB=(SELECT JOB FROM EMP WHERE ENAME='SCOTT') AND ENAME!='SCOTT'
5.列出薪金高于部门30中员工的薪金的所有员工的姓名和薪金,部门名称
a.求出30部门员工薪金
SELECT SAL FROM EMP WHERE DEPTNO=30;
b.以上面的查询作为子查询的条件
SELECT ENAME,SAL FROM EMP WHERE SAL IN(SELECT SAL FROM EMP WHERE DEPTNO=30)AND DEPTNO!=30
c.在之前的程序上进行修改,使用>all,比最大的还要大
SELECT ENAME,SAL FROM EMP WHERE SAL >ALL(SELECT SAL FROM EMP WHERE DEPTNO=30) AND DEPTNO!=30
d.与depth表关联,求出部门名称
SELECT E.ENAME,E.SAL,D.DNAME,D.LOC
FROM EMP E,DEPT D
WHERE E.SAL>ALL(SELECT SAL FROM EMP WHERE DEPTNO=30)AND E.DEPTNO!=30 AND E.DEPTNO=D.DEPTNO
6.列出每个部门工资的员工数量,平均工资和平均服务期限
a.每个部门工作的员工数量:求的时候可以求出部门名称
SELECT D.DNAME,COUNT(E.EMPNO)
FROM EMP E,DEPT D
WHERE E.DEPTNO=D.DEPTNO
GROUP BY D.DNAME
b.求出平均工资,和服务期限
SELECT D.DNAME,COUNT(E.EMPNO),AVG(E.SAL),AVG(MONTHS_BETWEEN(SYSDATE,E.HIREDATE)/12)年
FROM EMP E,DEPT D
WHERE E.DEPTNO=D.DEPTNO
GROUP BY D.DNAME
7.列出所有员工的姓名,部门名称和工资
直接两张表关联
SELECT E.ENAME,D.DNAME,E.SAL
FROM EMP E,DEPT D
WHERE E.DEPTNO=D.DEPTNO
8.列出所有部门的详细信息和部门人数
a.列出所有部门的人数
SELECT DEPTNO DNO,COUNT(EMPNO) COU
FROM EMP
GROUP BY DEPTNO
b.把以上的查询当做一张临时表出现
SELECT D.*,NVL(ED.COU,0)
FROM DEPT D,(SELECT DEPTNO DNO,COUNT(EMPNO) COU FROM EMP GROUP BY DEPTNO) ED
WHERE D.DEPTNO=ED.DNO(+)
9.列出各种工作的最低工资及从事此工作的雇员姓名
a.按工作分组,使用min()函数求出最低工资
SELECT JOB,MIN(SAL)
FROM EMP
GROUP BY JOB
b.按工资查出雇员信息
SELECT * FROM EMP WHERE SAL IN(SELECT MIN(SAL) FROM EMP GROUP BY JOB);
10.列出各个部门manager的最低薪金
SELECT DEPTNO,MIN(SAL)
FROM EMP
WHERE JOB='MANAGER'
GROUP BY DEPTNO
11.列出所有员工的年工资,按年薪从低到高排序。
a.在处理年薪的时候需要注意奖金,奖金要NVL函数处理
SELECT ENAME,(SAL+NVL(COMM,0))*12 INCOME FROM EMP ORDER BY INCOME;
12.查处某个员工的上级主管,并要求出这些主管中的新水超过3000
SELECT DISTINCT M.*
FROM EMP E,EMP M
WHERE E.MGR=M.EMPNO AND M.SAL>3000
13.求出部门名称中,只带'S'字符的部门员工的,工资合计,部门人数
a.查询部门表的部门名称,用模糊查询
SELECT DEPTNO FROM DEPT WHERE DNAME LIKE '%S%'
b.使用以上的结果作为新查询的条件
SELECT DEPTNO,SUM(SAL),COUNT(EMPNO)
FROM EMP
WHERE DEPTNO IN(SELECT DEPTNO FROM DEPT WHERE DNAME LIKE '%S%')
GROUP BY DEPTNO
14.给任职超过十年的加薪10%(这个问题是个批量跟新)
UPDATE EMP SET SAL=SAL+(SAL*0.1)WHERE MONTHS_BETWEEN(SYSDATE,HIREDATE)/12>10;
15.一道面试题:
现在有一张国家表,里面只有一个国家名称字段:内容如下:"中国,美国,巴西,荷兰",现在要求查询实现对战功能:
中国---美国
中国---巴西
中国---荷兰
美国---中国
美国---巴西
美国---荷兰
....
CREATE TABLE NATIONAL
(
NAME VARCHAR2(30)
);
INSERT INTO NATIONAL VALUES('中国');
INSERT INTO NATIONAL VALUES('美国');
INSERT INTO NATIONAL VALUES('巴西');
INSERT INTO NATIONAL VALUES('荷兰');
SELECT T1.NAME,T2.NAME
FROM NATIONAL T1,NATIONAL T2
WHERE T1.NAME<>T2.NAME;
查看参数描述:
select * from v$nls_parameters;