前言:本博客花费作者大量时间,转载请声明,原文章出自:http://yuemu.blog.51cto.com


一.oracle常用命令

1 show user;

查看登陆用户


2.conn[ect]

 conn system/密码@orcl conn sys/密码@orcl as sysdba(sysoper)

切换用户


3.disc[onnect]

断开连接。


4.passw[ord]   用户

以高级用户重置低级用户密码


5.exit

退出数据库



 

二.文件操作命令

1.start

调用外部的脚本

在C盘存放了 select * from dept; 的语句,并保存为dept.sql。

sql>start  d:\dept.sql


2.edit

说明:该命令可以编辑指定的脚本。

sql>edit   d:\dept.sql

在打开sql脚本文件里去编辑sql脚本.


3.spool

说明:该命令可以将sqlplus屏幕上的内容输入到特定的文件里

 sql>spool d:\dept.sql sql>select *from dept; sql>spool  off

注意:当spool off 后,方把所有输入写入到外部dept.sql里


4.&

解释:可以替代变量,变量的值有交互时由用户输入
sql>select* from dept  DNAME='&DNAME';


sql>根据提示输入相应的值




三.用户管理

sys   system(管理员)

scott(普通用户)


1.创建用户(sys    system 用户)

格式:create  user   name  identified  by  passwd


sql>create  user  edu  identified  by  system

注意:创建的edu并不能通过conn立刻登陆,需要进行下面一步


2.赋予用户相应的权限

grant  create session  to edu

sql>conn edu/password

则可以登录


综合场景

创建一个用户ware,然给后他分配权限,可以让ware登陆数据库,创建表,可以操作自己创建的表。

回收角色。最后删除用户

1.使用system创建ware用户,密码设置为system

create user  ware  identified system;


2.要想让ware登陆数据库,需要给其connect,resource权限;

 grant connect  to  ware; grant resource  to  ware;


3.使用ware用户登录.

conn  ware/system


4.ware创建一张表.

create  table  users(id    number)insert   into  users   values (1);select * from  users;


5.删除ware用户

drop  user  ware [cascade]


注意:当ware拥有自己的数据对象时,加上选项cascade,一并把该用户拥有数据对象删除


权限赋予

案例,创建WARE用户,让其能够查看SCOTT用户的emp表,


1.使用system创建ware用户,密码设置为system

create   user  ware  identified   system;


2.要想让ware登陆数据库,需要给其connect,resoure权限。

grant  connect  to  waregrant  resource  to  ware


3.使用scott用户登录系统

sql>conn  scott/passwordsql>grant  select  on  emp  to  ware;


sql>conn  system/passwordsql>grant   select on scott.emp  to ware


4.使用ware登陆

sql>conn  ware/systemsql>select* from scott.emp


用户profile口令管理(限制用户恶意登陆)

1.可以把profile想象成一个数据对象(文件,规则)

语法格式:sql>create   profile   规则名  limit  failed_login_attempts 3  password_lock_time  2;


案例:

允许某用户,最多尝试登陆3次,如果3次未登录成功,则锁定该用户,锁定用户不能登陆系统。

sql>conn  system/passwordsql>create   profile  user1  limit  failed_login_attempts  3  password_lock_time  2;sql>alter  user  scott  profile  user1;sql>conn  scott/xxx@rocl(连续输错3次密码账号锁定)


解锁:

sql>alter  user  scott  account  unlock;


用户profile口令管理(限制密码的使用期限)

语法:

sql>create  profile  规则名  limit  password_life_time  10  password_grace_time  2


案例:

对一个账号的密码做出限制,最多使用10天,宽限期为2天,到时候密码必须更改。

sql>create  profile  user2  limit  password_life_time  10  password_grace_time  2;sql>alter  user  scott  profile  user2;


此时修改oracle服务器的时间,往后延迟10天与12天,13天查看使用scott登陆的提示信息。

sql>conn  scott/system@orcl;(10天出现还有2天必须改密码) sql>conn  scott/system@orcl;(10天之后提示改密码)


删除profile

drop  profile  规则名 [cascade];




四.oracle 数据类型

三大类:文本,数值,时间

1.char(size)

存放定长的字符串,最大存放2000个字符。例如char(32),存放32个字符(超出不行,不够32位,用空格补齐)

sql>create table stu01(name char(32)); sql>insert  into  stu01  values('qidong'); sql>select * from stu01; sql>select  name,dump(name)  from  stu01;


2.varchar2(size)

解释:变长,最大可以存放4000个字符。

举例:

sql>create table stu02(name varchar2(16));sql>insert   into   stu02    values('leo');sql>select  * from stu02;sql>select  name,dump(name)  from  stu02;


总结:比如存放了‘leo’的3个字符,实际存放在数据库中,就占用了3个字符,其余的字符就被回收了。

说明:char好处是查询与检索速度较快


3.nchar(size)  nvarchar2(size)

说明:n代表的意思编码格式为unicode编码,无论中文或英文都以一个字符来存放数据,

举例:

比如“a”,占用是一个字符。

比如“祁”,占用一个字符。

而char与varchar2里,则不是。

“a”占用一个字符。“祁”占用两个字符。

原因:

nchar一个空间用两个字符,而char一个空间就是一个字节。

案例:

sql>create  table  soft_oracle(name  nchar(2));sql>insert  into   soft_oracle  values(‘ab’);

结果正确


sql>insert  into   soft_oracle  values(‘abc’);

结果错误


sql>insert  into   soft_oracle  values(‘数据’);

结果正确


4.clob(size)变长

说明:字符型的大对象,最大8TB,

应用场景:如果varchar2不够用了,使用clob


5.blob(size)变长

说明:二进制数据,可以存放图片/声音等, 8tb

但是,实际过程中很少把图片与声音放在数据库里面


6.number (p,s) 变长

1.number 可以存放整数,可以存放小数。

2.number(p,s)

说明:

p表示有效位,s表示小数位,范围p[1,38]   s[-84,127]


案例1:

number(5,2)

sql>create  table  test1 (price  number(5,2));sql>insert  into test1  values (-999.99);

结果:-999.99


sql>insert  into test1  values (575.34);

结果:575.34


sql>insert  into test1  values (575.345);

结果:575.35


sql>insert  into test1  values (1000);

结果失败,超过范围,1000整数位超过3 位


案例2:

number(5)==number(5,0)

表示的范围:-99999~99999


案例3:

123.89  number

结果:123.89


案例4:

123.89  number(3)

结果:124


案例5:

123.89  number(6,2)

结果123.89


案例6:

123.89  number(6,1)

结果:123.9


案例7:

123.89  number(4,2)

结果:报错,长度超出了有效长度(4)


案例8:

123.89 number(6,-2)

结果:100


总结:

1.实际过程中如果项目明确要求了精确到多少位,number类型里面应该写明有效位和小数位,当不明确的时候直接为number,不标明有效位和小数位

2.number 是变长。

3.p为有效位(从左边第一个非0的数值开始)s位小数位。


7.date日期类型

说明:oracle  dd-mm-yy

案例:

sql>create  table  test1(birth   date);sql>insert   into  test('2011-11-11')

结果是错误

sql>insert  into test1 (01-1月-14');

结果正确


案例:银行里建的开卡信息

字段

字段类型

ID

number

name

varchar2(64)

sex

char(2)

birth

date

money

number(10,2)


修改表中字段

Alter

格式:

alter  table  tablename

add      (字段名  字段类型)------------------------------------------- 添加字段


alter  table   tablename

modify   (字段名   字段类型) --------------------------------------修改字段


alter  table   tablename

drop  column  字段名       ---------------------------------------------删除字段




五.sql基础语法


insert

注意事项

1.插入的数据应与字段的数据类型相同。

insert  into 表名 (字段名1,字段名2)  values(数据1,数据2)

sql>insert  into  test1(id)  values(10);


正确

sql>insert  into  test1(id)   values('abc');


错误

2.数据的大小应该在列的规定范围之内

 sql>create  table tset2(name  varchar2(2)); sql>insert   into  test2(name)   values('aabb');


错误

3.在values中列出数据位置必须与字段列的数据类型排列相对应

4.字符和日期数据包含''中。

5.插入空值,不指定或null.


update

格式:

update    表名    set   列名=值   where   条件


案例1:

update语法可以用新值更新原有表中的各列:

sql>update  stu  set  sex='女'  where id=1;


update语句中,set子句指示要修改哪些列和赋予哪些值

给所有用户的钱都增长1.2倍

 sql>update  stu  set  money=money*1.2  sql>update   stu  set  money=money*1.2  where 1=1


当更新所有的行的时候,where可以省略(where1=1代表所有行都满足条件)


delete

基础语法:

delete  from  表名  where  条件


注意事项:

1.如果不使用where子句时,将表中所有数据全部删除。

2. 如果要删除某列的值,delete是不可以做到

3.删除整个表的drop  表名。

4.使用delete的时候,一定考虑表之间的参照完整性。


案例:

删除某一行记录

sql>delete  from  stu  where  name='aaa';


5.truncate  table  表名;

sql> truncate  table   stu;


注意:1.一旦使用了truncate 表中的数据不可恢复。

2.当确定表中的数据没用时,truncate删除效率更快


rollback

回滚的使用

sql>savepoint  回滚点名字sql>delete  from  stu;sql>select  * from  stu;


无结果

sql>rollback    to    回滚点名字sql>select   *  from    stu;


发现删除的数据又回来了。




六.select语句

基本语法:

select  [distinct] *(或字段名)  from  表名  where;

1.select  指定查询哪些列;

2.distinct  去掉重复行;


举例:

1.查看表结构

sql>desc  表名;


2.查询所有列

sql>select  *  from  emp;


3查询指定列

sql>select   ename,sal    from  emp;


4.取消重复行(所有列数据都一样)

sql>select   distinct    deptno,job   from  emp;


算术表达式

1.使用算术表达式

案例:显示每个员工的年工资

sql>select  ename,sal*12  from  emp;


2.给列起别名

sql>select  ename as"姓名", sal*12  as"年薪"  from  emp;sql>select  ename "姓名", sal*12  "年薪"  from  emp;sql>select  ename 姓名, sal*12  年薪  from  emp;


3如何处理null值

案例:员工1年能挣多少钱

sql>select   ename,sal*12+comm*12  from  emp;


结果异常,有员工工资为空。

sql>select   ename,sal*12+nvl(comm,0)*12  from  emp;


nvl 函数:nvl(comm,0)  如果comm为空null则返回0,否则返回自身


4.如果链接字符串(||)

sql>select  ename    ||'的薪水是'||  (sal*12+nvl(comm,0)*12)  from   emp;




七.where子句

如何显示工资高于3000的员工,

sql>select  * from  emp  where  sal>3000;


如何查找1982.1.1后入职的员工

sql>select  * from  emp  where to_char(hiredate,'yyyy-mm-dd')>'1982/1/1';


如何查找1981年后入职的员工

sql>select  *  from  emp  where  to_char(hiredate,'yyyy')>'1981';


如何显示工资在2000至2500之间。

sql>select  *  from  emp  where  sal>=2000  and sal<=2500;


sql>select  *  from  emp  where  sal  between  2000  and 2500;


like(模糊查询)

%表示任意0到多个字符,_表示的是任意单个字符

1.如何显示首字母为s的员工的姓名和工资

sql>select  ename,sal  from  emp  where  ename  like 's%'


2.如何显示第3个字符为大写o的员工信息

sql>select  ename,sal   from  emp  where   ename  like  '___O%'


in

1.如何显示empno 7369,7499,7521的雇员信息

sql>select * from emp  where  empno=7369  or empno=7499 or empno=7521;


sql>select  *  from emp where empno  in (7369,7499,7521);


使用is null 的操作符

1.如何显示没有上级的雇员信息

sql>select  *  from  emp  where  mgr  is  null;


使用逻辑操作符号

1.查询工资高于500或为manager的雇员,同时满足他们的首字母为大写J;

sql>select * from  emp  where (sal>500  or  job='manager')  and (ename like  'J%');


Order  by  (排序)

1.如何按照工资的从低到高的顺序显示雇员的信息

sql>select  *   from  emp  order  by  sal[asc];


2.按照部门号升序而雇员入职时间为降序排列

sql>select *  from emp order  by  deptno,hiredate  desc;


使用列的别名

1.

sql>select  ename,sal*13  as"年薪" from  emp  order  by "年薪";


2.

select  ename,sal*13+nvl(comm,0)*13 as "年薪"  from  emp;



八.复杂查询

复杂查询:复杂查询就是要显示多张表的数据;

max\min\avg\sum\count 聚合函数


1.如何显示所有员工的最高工资和最低工资

 sql>select max(sal)  from  emp; sql>select  min(sal)  from  emp;


2.查询该公司最大年工资的人

sql>select  max(sal*13+nvl(comm,0)*13)  "年薪"  from  emp;


返回值为65000

注意:如果结果里面有2人年薪达到65000,max只返回一个,这个是随机的

3.显示所有员工的平均工资和工资总和

select  avg(sal),sum(sal)  from emp;


AVG如果列表值有空,不能统计过来

sql>select  avg(comm)  from  emp;

注意:avg只统计了4个人,实际共14个人


用 

select  sum(comm)/count(*)  from  emp; 或select   avg(nvl(comm,0)) from emp;


统计多少人有奖金,并算出奖金平均值

sql>select count(comm)  from  emp;


注意:count统计的是非空的值


其他深度要求

请显示工资最高的员工的姓名,工作岗位

思路:

1.先查询工资最高的工资是多少

select max(sal) from emp;


2.在查询等于max(sal)

select  ename,job  from emp where  sal=(  select   max(sal)   from emp;);


3.请显示工资高于平均工资的员工信息

sql>select ename,job,sal from emp where sal>(select  avg(sal)  from emp);


group  by  和 having 子句

group  by :用于对查询的结果进行分组统计

having:和where 差不多,在group by 中使用。


如何显示每个部门的平均工资和最高工资

1.先分组(使用group by)

group  by depnto


2,在分组结果上进行筛选。

sql>select  depnto,avg(sal),max(sal)  from emp  group by depnto;


显示每个部门的每种岗位的平均工资和最低工资

sql>select  deptno,avg(sal),max(sal)  from  emp  group  by  deptno,job;


①.显示部门平均工资低于2000的部门号和它的平均工资;

思路:确定子查询

1.查询各个部门平均工资;

2.在1的执行结果里,挑选出低于2000的

sql>select  deptno,avg(sal)  from  emp group  by  deptno having   avg(sal)<2000;




九.多表查询

需求:实际过程中经常使用多表联合查询

1.显示雇员的名字,工资及所在部门的名字。

sql>select emp.ename,emp.sal,dept.deptno from emp,dept where  emp.deptno=dept.deptno;


注意:当使用多表联合查询时,如果不带任何条件(where)会出现笛卡尔积

规定:多表查询的条件(where)是至少不能少于表的个数-1


2.如何显示部门号为10的部门名称,员工名和工资

sql>select emp.ename,emp.sal,dept.dname  from  emp,dept   where  emp.deptno=dept.deptno  and  dept.deptno=10;


3.显示各个员工的名字,工资,及工资的级别

sql>select  ename,sal,grade  from  emp,salgrade    where   emp.sal  between losal  and  hisal;


4.扩展

显示雇员名称,雇员的工资及 所在部门的名字,并按部门排序

select  ename,sal,dept.name  from  dept,emp   where  dept.deptno=emp.deptno  order by  dept.dname;


自身连接

显示员工的上级姓名

比如:显示'SMITH'的上级

sql>select ename  from emp  empno=( select mgr  from emp  where  ename='SMITH');


扩展要求:

显示各个员工的姓名和他的上级领导的名字

sql>select  a.ename,b.ename   from   emp  a,emp  b  where  a.mgr=b.empno;


以上结果,发现没有king(因为king没有上级)如果让king出现,使用左连接或右连接。




十.子查询

定义:子查询是指嵌入在其它sql语句中的select语句,嵌套查询:

单行子查询:

是指只返回一行数据的子查询语句

如何显示与SMITH同一部门 的员工

1.先查询SMITH在哪个部门

sql>select deptno from emp where ename='SMITH'


2.在查询该部门的所有员工

sql>select * from emp where  deptno=(sql>select deptno from emp where ename='SMITH');


如果不显示SMITH

sql>select * from emp where  deptno=(sql>select deptno from emp where ename='SMITH')  and  ename!='SMITH';


多行子查询

是指返回多行数据的子查询:

如何查询和部门号为10员工所参加的工作岗位相同工作岗位的雇员的名字,岗位,工资,部门号。

1.查询出10号部门有哪些工作岗位

sql>select  job  from emp  where  deptno=10;


2.显示和10号部门从事岗位的雇员信息

sql>select *  from emp where job in (sql>select  job  from emp  where  deptno=10);


ALL

如何显示工资比30号部门最高工资高的员工信息

1.查询30号部门工资最高

sql>select max(sal)  from  emp  where  deptno=30;


2.查询比30号最高工资还高雇员的信息

select  *  from emp  where  sal>(sql>select max(sal)  from  emp  where  deptno=30);


select * from emp  where sal > all(select   sal from emp  where deptno=30);


ANY

如何显示工资比30号部门最低工资低

的员工信息

select * from emp where sal >any(select sal frpm  emp  where deptno=30)


多列子查询

如何查询与SMITH的部门和岗位完全相同的所有雇员信息。

1.查询SMITH所在部门和所从事的工作岗位

sql>select job,deptno  from emp where  ename='SMITH'


2.查询与SMITH同部门,同岗位的员工信息

sql>select * from emp where  job =(select  job from emp  where  ename='SMITH')  and deptno=(select  deptno  from  emp  where ename='SMITH');


推荐使用方式

select * from emp where(job,deptno)=(select job,deptno  from emp where  ename='SMITH');


单行子查询是返回单列,单数据,多行子查询是返回单列多行数(都针对单列而言);而多列子查询则是查询返回多个数据的子查询语句


FROM

在from子句中使用子查询

如何显示高于自己所在部门平均工资的员工信息

1.查询各个部门的平均工资

sql>select  deptno,avg(sal)  from emp group  by deptno;


2.把1产生的结果当成一个临时表对待,再进行加工

sql>select * from emp,(select  deptno,avg(sal)  avgsal from emp group  by deptno) T1 where T1.deptno=emp.deptno  and  emp.sal>T1.avgsal;


查询各个部门工资最高的员工信息

sql>select  * from  emp T1,(select deptno,max(sal) maxsal  from emp group  by deptno)  T2  where  T1.deptno=T2.deptno  and  T1.sal=T2.maxsal;


显示每个部门的信息和人员数量

1.先统计一下各个部门有多少人

select  deptno,count(*)  from emp group by deptno;


2.把1当成临时表(从这个临时表可以获取每个部门多少人)然后结合dept表,完成查询。

select  * from dept  t1,(select  deptno,count(*)  from emp group by deptno)  t2  where  t1.deptno=t2.deptno;


总结:FROM子句中使用子查询时,该子查询会被作为一个临时表来对待。必须给予查询指定别名




十一.分页查询

重点:分页查询是必须掌握的一个要点

select * from emp;


如果想要第4行至第6行的内容?


选择小于6行的数据

select  empno,ename,rownum  from  emp where  rownum<=6;


显示4到6行数据

select * from (select rownum n,empno,ename,hiredate from emp where rownum<=6) t1 wheret1.n>=4


总结:


第1次筛选:rownum<=6  当成临时表

第2次筛选; rownum>=4


一.请按入职时间的先后进行排序,查询7到10行的数据

select * from (select rownum n,empno,ename,hiredate from emp where rownum<=10) t1 wheret1.n>=7 order by hiredate




十二.内链接与外连接

内链接

内链接实际上就是利用where子句对两张表形成的笛卡儿积进行筛选

内链接:是最常用的一种连接方式

案例:显示员工的信息和部门名字


方法1:

select emp,empno emp.ename,dept.dname  from emp,dept  where  emp.deptno=dept.deptno;


方法2:s

elect emp,empno emp.ename,dept.dname  from emp inner join dept  onemp.deptno=dept.deptno;

格式:select  列名   from  表1  inner  join  表2

on  条件


外连接

外连接:左外连,右外链,完全连接

1.左外连接:如果左侧的表完全显示,就是左外连接

2.右外连接:如果右侧的表完全显示,就是右外连接

3.完全连接:如果表完全显示,就是完全连接


左连接

案例:显示所有人成绩,如果没有成绩,也要显示该人的姓名和id ,该同学成绩为空

方法1:

select  stu.id,stu.name,exam.grade  from  stu left  join  exam onstu.id=exam.id


方法2:

select stu.id,stu.name,exam.grade  from  stu,exam  where  stu.id=exam.id(+);


右连接

案例:显示所有成绩,如果没有名字匹配,则显示空

方法1:select  stu.id,stu.name,exam.grade  from  sturight  joinexam onstu.id=exam.id 

方法2: select  stu.id,stu.name,exam.grade  from  stu, exam  where  stu.id(+)=exam.id;


完全连接

案例:显示所有成绩,所有人

select  stu.id,stu.name,exam.grade  from  stu full  joinexam onstu.id=exam.id