Java进阶知识01 Oracle数据库,基础知识

本文知识点(目录):

    1、Oracle的五大约束条件
    2、在PLSQL developer中连接数据库的操作
    3、Oracle的基本数据类型
    4、dos命令行(连接数据库和一些简单授权操作)
    5、Oracle SQL和Oracle的关系
    6、创建数据库的方法(从创建数据库到创建用户,再到授权,最后到建表一些简单操作)
    7、oracle基本操作语句(一些常用的dos命令行操作语句)
    8、oracle操作数据表的语句【命令行操作指令】
       8.1、select 子句
       8.2、where 子句
       8.3、order by 子句
       8.4、单行函数
       8.5、隐式转换
       8.6、通用函数和条件判断
       8.7、多行函数、group by 子句
       8.8、多表查询
       8.9、子查询
       8.10、集合查询
       8.11、Oracle分页(分页查询)
       8.12、约束和表、表结构、表内数据的CRUD操作
       8.13、Oracle事务
       8.14、Oracle视图
       8.15、Oracle序列
       8.16、Oracle索引



1、Oracle的五大约束条件:

a、主键  primary key
b、外键  foreign key,
c、唯一  unique,
d、检测  check
e、非空  not null

实例运用

-- 商品表   客户表   购物车表
/*
商品表 goods  编号gid , 名称 , 价格 ,厂商
客户表 customer 编号cid  ,姓名,性别,出生日期,身份证
购物车表 purchase  商品编号,客户编号,商品数量
请建立表,要求 必须有主外键,所有的名称不能为空,价格必须大于0,身份证必须唯一,性别必须是男女默认男,商品数量必须是1到30之间
*/
create table goods(
gid number(8) primary key,
gname varchar2(50) not null,
price number(15,2) check(price >0),
firm varchar2(100)
);

create table customer( 
cid number(8) primary key,
cname varchar2(30) not null,
sex char(2) default '' check (sex in ('','')),
birth date,
idcard  char(18) unique
);
create table purchase ( gid number(8) references goods(gid), cid number(8) references customer(cid), goodsnum number(8) check( goodsnum between 1 and 30) );

2、在PLSQL developer中连接数据库的操作

1 ---管理员登录
2 conn sys/oracle@orcl as sysdba;
3 --解锁scott用户
4 alter user scott account unlock;
5 -- scott:用户名; tiger:新密码
6 alter user scott identified by tiger; 
7 --scott登录 
8 conn scott/tiger@orcl as normal;

 

3、Oracle的基本数据类型

可参照:http://blog.csdn.net/weixin_41278231/article/details/78716417

1) 数字型 number [小数,整数]
    number(5,3)表示总共5个数字,小数点后3个,最大值99.999
    number(5) 表示整数  最大值99999

2) 字符型 

   char  定长字符 : char(10)   如果没有达到10字符就用空格补充,他所占的大小总是10字符空间
   varchar2  变长字符和varchar类似 :varchar2(10) 如果没有达到10个字符长度不用空格补充
   clob   大文本类型:文字很多,小说,简介,新闻内容...
   blob  大文本类型: 图片,文件,压缩文件...
   
3)时间型

    date    年月日 时分秒
    timestamp   年月日 时分秒  秒可以带小数点(精确到0点几秒)

 4、dos命令行

1连接数据库  
在命令提示符中运行:
  C:\Adminstrator> sqlplus sys/change_on_install@orcl as sysdba 或者  sqlplus sys/change_on_install as sysdba
  或者 C:\Adminstrator> sqlplus / as sysdba  -- 如果有多个数据库,建议用第一种方法,密码后面带上数据库名称,否则,默认连接登录的是最近一次新建的数据库。
在Oracle的PL/SQL Developer中的SQL命令行工具中运行:
  SQL> conn sys/change_on_install@orcl as sysdba; -- 解析:as SYSDBA:连接为数据库管理员。@后面的orcl是数据库名称。   SQL
> conn userName/user@orcl as normal-- 格式:conn 用户名/密码@数据库名 as normal;   解析:as normal:连接为normal(普通数据库用户). 解析:sys:用户名(超级管理员) change_on_install:(默认)密码 sysdba:连接身份 连接身份:一共三种,分别为 sysdba:系统管理员 sysoper:系统操作员 normal:普通用户 2解锁用户: SQL> alter user scott account unlock; 修改密码: SQL> alter user scott identified by 123 -- scott:用户名; 123:新密码 3以scott普通用户的身份进入 SQL> sqlplus scott/tiger 或者 sqlplus scott/tiger@orcl -- @跟你要连接登录的数据库名称 -- 注:oracle的关键字(比如sqlplus/as)不区分大小写,用户名(如scott/sysdba)不区分大小写,但是密码严格区分大小写. SQL> select status from v$instance; -- v$动态表开头,查看动态实例,open为启动。 SQL> shutdown immediate -- 关闭数据库 SQL> startup  -- 继续启动 SQL> show parameter db_name  -- 查看数据库名称 -- 查询当前连接的数据库下的SCOTT用户的默认状态 SQL> select username,account_status from dba_users where username='SCOTT'; SQL> desc emp;  -- 查询表结构,emp:员工表 SQL> show user -- 查看当前已连接数据库的用户

5、Oracle SQL和Oracle的关系 

  (1)第四代语言:SQL【结构化查询语言,面向关系的】
      第一代:机器语言
      第二代:汇编        
      第三代:C/C++/C#/Java/VB/...
      第四代:SQL
      将来。。。

  (2)SQL92/99 标准的四大分类
     (A)DML(数据操纵语言):select,insert,update,delete  
     (B)DDL(数据定义语言):create table,alter table,drop table,truncate table  。。。
     (C)DCL(数据控制语言):grant 权限 to scott,revoke 权限 from scott  。。。
     (D)TCL(事务控制语言):commit,rollback,rollback to savepoint 。。。

  (3)oracleSQL与SQL92/99的关系
     SQL92/99标准,访问任何关系型数据库的标准
     oracleSQL语言,只访问Oracle数据库服务器的专用语言

  (4)Java技术和oracleSQL的关系
     JDBC-->使用OracleSQL语法-->Oracle服务器--->orcl数据库-->表-->记录
     Hibernate-->使用OracleSQL语法-->Oracle服务器
     MyBatis-->使用OracleSQL语法-->Oracle服务器

=========================================================================================================================================

 

6、创建数据库的方法 http://www.cnblogs.com/manmanlu/p/5993449.html

1、数据库创好后,给数据表分配大小(可忽略此步)  

create tablespace day48ssh datafile 'S:\OracleDB\oradata\day48ssh\day48ssh_data.DBF' size 500M;   

解析:day48ssh数据库名称         

    size 500M给数据表分配的空间大小

    'S:\OracleDB\oradata\day48ssh\day48ssh_data.DBF'本地路径

2、新增用户zhao/1234   

创建用户:create user zhao identified by 1234

授予用户使用表空间的权限:alter user zhao quota unlimited on day48ssh

授予zhao用户创建session的权限,即登陆权限:grant create session to zhao

授予zhao用户创建table的权限:grant create table to zhao

授予zhao用户创建sequence的权限:grant create sequence to zhao

授予zhao用户操作表空间的权限:grant resource to zhao

 

或者一键授权:

grant create session,create table,create sequence,create view,resource to zhao

3、执行建表脚本(创建表) “案例表”   

create table users(

     id number(5) primary key,

     account varchar2(20) not null,

     password varchar2(20) not null

);

创建序列:create sequence users_seq;  由于oracle没有自增长,所以...

插入一条记录:insert into users values(users_seq.nextval,'zhao','123456');

=========================================================================================================================================

 

调整dos命令行显示数据表的格式(简称:好看格式,就是把凌乱的格式转化为一个好看的表的形式,蓝色为表的字段名):

这个是orcl数据库下的scott用户的emp表:(number(int)类型用9作占位符,其他类型都可用a,a后面用数字长度作占位符)

col empno for 9999;
col ename for a10;
col job for a10;
col mgr for 9999;  
col hiredate for a12;
col sal for 9999999;
col comm for 9999999;
col deptno for 99;
set pagesize 20;

表结构图:

未设置前的效果图:

设置完成后,显示效果图(好看多了,不像之前那样凌乱了):

PS:假如,我要创建一个新表叫c_emp,并且c_emp中的字段和表内数据要和emp表的相同,则:

create table c_emp as select * from emp;  -- 创建一个和emp表一模一样的表c_emp,只有表名不同

============================================================================================================================================

 

4、Oracle用户创建及权限设置

1)、普通用户scott默认是未解锁,不能直接使用,需要解锁(alter user scott account unlock;)。如果是新建的用户,则没有任何权限,必须授予权限:

  grant create session to zhangsan; //授予zhangsan用户创建session的权限,即登陆权限

  grant unlimited tablespace to zhangsan; //授予zhangsan用户使用表空间的权限

  grant create table to zhangsan; //授予创建表的权限

  grant drop table to zhangsan; //授予删除表的权限

  grant insert table to zhangsan; //插入表的权限

  grant update table to zhangsan; //修改表的权限

  grant all to public; //这条比较重要,授予所有权限(all)给所有用户(public)

2)oralce对权限管理比较严谨,普通用户之间也是默认不能互相访问的,需要互相授权

  grant select on tablename to zhangsan; //授予zhangsan用户查看指定表的权限

  grant drop on tablename to zhangsan; //授予删除表的权限

  grant insert on tablename to zhangsan; //授予插入的权限

  grant update on tablename to zhangsan; //授予修改表的权限

  grant insert(id) on tablename to zhangsan;

  grant update(id) on tablename to zhangsan; //授予对指定表特定字段的插入和修改权限,注意,只能是insert和update

  grant alert all table to zhangsan; //授予zhangsan用户alert任意表的权限

、撤销权限

 基本语法同grant,关键字为revoke

、查看权限

 select * from user_sys_privs;//查看当前用户所有权限

   select * from user_tab_privs;//查看所用用户对表的权限

四:查询/查看

查看当前的所有数据库: select * from v$database;
     select name from v$database;
查看数据库结构字段desc v$databases;

=========================================================================================================================================

 

************************************* oracle基本操作语句 ************************************

打开服务器
net start oracleservicebinbo
打开监听器
lsnrctl start
关闭服务器
net stop oracleservicebinbo
关闭监听器
lsnrctl stop
===============================================================
清屏: clear screen 或 host cls
退出: exit 或 quit
===============================================================
查看当前用户的角色
SQL>select * from user_role_privs;
===============================================================
查看当前用户的系统权限和表级权限
SQL>select * from user_sys_privs;
SQL>select * from user_tab_privs;
===============================================================
查看当前用户的缺省表空间
SQL>select username,default_tablespace from user_users;
===============================================================
换用户
conn as sysdba
sys
tsinghua
sqlplus "sys/tsinghua as sysdba"
conn sys/zl as sysdba
===============================================================
修改表结构
alter table test modify(name not null);
alter table test add(name varchar2(20));
alter table test drop column sex;
alter table test set unused column sex;
alter table test drop unused columns;
===============================================================
更改用户密码
sql>alter user 管理员 identified by 密码;
===============================================================
创建表空间的数据文件
sql>create tablespace test datafile 'd:oraclebinbo.dbf' size 10m;
===============================================================
创建用户
sql>create user 用户名 identified by 密码;
===============================================================
bfile类型实例
创建目录
create directory tnpdir as 'c:';
删除目录
drop directory tnpdir
授权 (读数据库目录和文件的权限)
grant read on directory tnpdir to scott;         用户:scott
建表
create table bfiletest(id number(3), fname bfile);
添加数据
insert into bfiletest values(1,bfilename('TMPDIR','tmptest.java'));
===============================================================
查看用户
sql>show user
===============================================================
检查语句是否有错
show error
===============================================================
锁定用户
sql>alter user 用户名 account lock
===============================================================
解除(锁)用户
sql>alter user 用户名 account unlock
===============================================================
删除用户
sql>drop user zl;
===============================================================
给用户创建表权限
sql>grant create table to 用户名;
===============================================================
授管理员权限
sql>grant dba to 用户名;
===============================================================
给用户登录权限
sql>grant connect to 用户名
===============================================================
给用户无限表空间权限
sql>grant unlinmited tablespace to 用户名;
===============================================================
收回权限
sql>revoke dba from 用户名;
===============================================================
查看用户下所有的表
SQL>select * from user_tables;
===============================================================
查看名称包含log字符的表
SQL>select object_name,object_id from user_objects
   >where instr(object_name,'LOG')>0;
===============================================================
查看某表的创建时间
SQL>select object_name,created from user_objects where object_name=upper('&table_name');
===============================================================
查看某表的大小
SQL>select sum(bytes)/(1024*1024) as "size(M)" from user_segments
   >where segment_name=upper('&table_name');
===============================================================
查看放在ORACLE的内存区里的表
SQL>select table_name,cache from user_tables where instr(cache,'Y')>0;
===============================================================
再添加一个表空间的数据文件
sql>alter tablespace test add datafile 'd:oracletest1.dbf' size 10m;
===============================================================
建表    
SQL
>create table studen(stuno int,stuname varchar(8) not null,stubirth date default to_date('1987-5-9','YYYY-MM-DD')); 向表结构中加入一列
SQL
>alter table studen add(stuphoto varchar(9)); 从表结构中删除一列
SQL
>alter table studen drop column stuphoto; 修改表一列的长度
SQL
>alter table studen modify(stuno number(4)); 隐藏将要删除的一列
SQL
>alter table studen set unused column stuphoto; 删除隐藏的列
SQL
>alter table studen drop unused columns; 向表中加入约束
SQL
>alter table studen add constraint pk primary key(stuno); 删除约束
SQL
>alter table studen drop constraint pk; =============================================================== 创建表 sql>create table 用户名(name varchar2(20),password varchar(20)) tablespace 空间名; =============================================================== 添加字段 sql>alter table test add(column_x char(10) not null); =============================================================== 更改字段 sql>alter table emp modify(column_x char (20)); =============================================================== 删除字段 如待删除域属于某个索引,则不允许删除操作,必须将此域先设置为NULL。 sql>alter table emp modify(column_x null); sql>update emp set column_x=null; sql>commit; sql>alter table emp drop(column_x); =============================================================== 选择表空间 sql>alter user 用户名 default tablespace test; =============================================================== 管理员删除别的用户中的表 sql>drop table 用户名.表名; =============================================================== 退出 sql>exit; 或 sql>quit; =============================================================== 默认进入 sql>sqlplus "/ as sysdba" =============================================================== 查看数据库 sql>show parameter block; =============================================================== 写大量语句用记事本,新建方式。 输入"ed"回车 保存后 输入"/"运行; =============================================================== 查询用户有多少表 sql>select * from tab;

 

************************************* oracle操作数据表的语句 ************************************

 1、【命令行】select 子句

 1 ------------------------ select子句 ------------------------
 2 
 3 -- 命令行窗口:scott用户连接登录orcl数据库
 4 sqlplus scott/tiger@orcl
 5 ===============================================================
 6 -- 1、查询emp表的结构
 7 desc emp;
 8 -- 2、查询emp表的全部数据
 9 select * from emp;
10 -- 3、查询emp表的指定数据
11 select empno,ename from emp;
12 ===============================================================
13 -- 4、select子句大小写和别名问题
14    -- Sql语句的关键字、列名、表名大小写不敏感,但是建议大写
15    select empno,ename from emp; 或 SELECT empno,ename From emp; 或 select empNO,ename FROM emp; -- 等等,都可以
16    -- 别名:用as关键字(as可以省略)
17    select empno as "编号",ename as "姓名",sal as "工资",deptno as "部门号" from emp;
18    -- 或者
19    select empno "编号",ename "姓名",sal "工资",deptno "部门号" from emp;
20 -- 注意:别名可以要双引号,也可以不要,但是不能用单引号;
21 -- 如果别名中有空格,必须要用双引号;因为在oracle中单引号表示字符串类型或者是日期类型。
22 -- 列名不能使用单引号,因为oracle认为单引号是字符串型或日期型
23 select empno as "编号",ename as 姓名,sal "月    薪" from emp;
24 ===============================================================
25 -- 5、拼接符||
26 select ename || '的薪水是' || sal || '美元' from emp;  -- 运行结果:***的薪水是***美元
27 ===============================================================
28 -- 6、去重(distinct 去除重复)
29 select distinct ename from emp;
30 ===============================================================
31 -- select子句的计算
32 select ename as "姓名",sal*12 as "年薪" from emp; -- 注意:任何一个NULL值与数字运算的结果都是NULL。
33 ===============================================================
34 -- 7、NULL的处理
35 select ename,comm+100 as comm from emp;
36 -- Oracle提供了一个函数:NVL(a,b)  ——如果a的值是null,取b的值;否则就取a的值。
37 select ename,NVL(comm,0)+100 as comm from emp;  -- NVL(a,b)可以小写,nvl(a,b)
38 -- 或者使用哑表来查询:dual
39 select nvl(null,10) from dual; -- 只是做个演示
40 ===============================================================
41 -- 8、显示系统时间
42 select sysdate from dual; -- 使用sysdate,显示系统当前时间,在默认情况下,oracle只显示日期,而不显示时间,比如:26-4月-15.
43 ===============================================================
44 -- 9、Oracle读(解析和执行)、写(生成).sql文件
45 spool e:/oracle-day01.sql; -- 使用spool命令,解析执行。
46 -- spool e:/oracle-day01.sql;开始,spool off;结束。 中间不管执行多少SQL语句,都将写到硬盘e:\oracle-day01.sql文件中。
47 spool off; -- 使用spool off命令,结束spool语句,并保存SQL语句到硬盘e:\oracle-day01.sql文件中。
48 @ e:/crm.sql; -- 使用@命令,将硬盘文件e:\crm.sql,读到orcl实例中,并执行文件中的sql语句。
49 ===============================================================
50 -- 10、Oracle的注释
51   使用--符号,设置单行注释
52   使用/* */符号,设置多行注释
53 
54 -- 小结:其他语言的注释符号
55    html: <!--  -->
56    css:/*   */
57    js:/*   */ 或 //
58    xml:<!--  -->
59    jsp:<!--  -->
60    mysql: -- 或 #
61    oracle:-- 或 /*   */
62    java:/*   */ 或 //
63    properties:#
64 ===============================================================
65 -- 11、sql 和 sql plus 的小结
66    -- SQL语句的特点:
67       1)是SQL92/99的ANSI官方标准,只要按照该标准来写,在任何的关系型数据库中都可以直接执行
68       2)SQL语句的关健字不能简写,例如:selectwherefrom
69       3)大小写不敏感,提倡大写 
70       4)能够对表数据进行增删改查操作
71       5)必须以分号结束
72       6)通常称做语句
73 
74    -- SQL PLUS命令的特点:
75       1)是oracle自带的一款工具,在该工具中执行的命令叫SQLPLUS命令
76       2)SQL PLUS工具的命令中的关健字可以简写,也可以不简写,例如:col ename for a10;  -- col是column的缩写
77       3)大小写不敏感,提倡大写
78       4)可以不用分号结束,也可以用分号结束(限于连接登录时,等个别指令),个人提倡:不管SQL或SQL PLUS,都以分号结束
79       5)通常称做命令,是SQL PLUS工具中的命令

2、【命令行】where 子句

 1 ------------------------  where子句 ------------------------
 2 
 3 -- 1、查询emp表中20号部门的员工信息
 4 select * from emp where deptno = 20;
 5 ===============================================================
 6 -- 2、查询姓名是SMITH的员工,字符串使用'',内容大小写敏感
 7 select * from emp where ename = 'SMITH';
 8 ===============================================================
 9 -- 3、查询1980年12月17日入职的员工,注意oracle默认日期格式(DD-MON-RR表示2位的年份)
10 select * from emp where hiredate = '17-12月-80';
11 ===============================================================
12 -- 4、查询工资大于1500的员工
13 select * from emp where sal > 1500;
14 ===============================================================
15 -- 5、查询工资不等于1500的员工 【 != 或 <> 】 
16 select * from emp where sal <> 1500;
17 select * from emp where sal != 1500;
18 ===============================================================
19 -- 6、查询薪水在1300到1600之间的员工,包括1300和1600
20 select * from emp where (sal>=1300) and (sal<=1600);
21 -- 或者
22 select * from emp where sal between 1300 and 1600;
23 ===============================================================
24 -- 7、查询薪水不在1300到1600之间的员工,不包括1300和1600
25 select * from emp where sal not between 1300 and 1600;
26 ===============================================================
27 -- 8、查询入职时间在"1981-2月-20"到"1982-1月-23"之间的员工
28 select * from emp where hiredate between '20-2月-81' and '23-1月-82';
29 -- 注意:
30    -- 1)对于数值型,小数值在前,大数值在后
31    -- 2)对于日期型,年长值在前,年小值在后
32 ===============================================================
33 -- 9、查询20号或30号部门的员工,例如:根据ID号,选中的员工,批量删除
34 select * from emp where (deptno=20) or (deptno=30);
35 -- 或者
36 select * from emp where deptno in (30,20);
37 ===============================================================
38 -- 10、查询不是20号或30号部门的员工
39 select * from emp where deptno not in (30,20);
40 ===============================================================
41 -- 11、查询姓名以大写字母S开头的员工。 使用%表示0个,1个或多个字符
42 select * from emp where ename like 'S';
43 -- 等价
44 select * from emp where ename = 'S';
45 select * from emp where ename like 'S%';
46 -- 注意:
47    -- 凡是精确查询用=符号
48    -- 凡是不精确查询用like符号,我们通常叫模糊查询
49 ===============================================================
50 -- 12、查询姓名以大写字母N结束的员工
51 select * from emp where ename like '%N';
52 ===============================================================
53 -- 13、查询姓名第一个字母是T,最后一个字母是R的员工
54 select * from emp where ename like 'T%R';
55 ===============================================================
56 -- 14、查询姓名是4个字符的员工,且第二个字符是I,使用_只能表示1个字符,不能表示0个或多个字符
57 select * from emp where ename like '_I__';
58 ===============================================================
59 -- 15、插入一条姓名为'T_IM'的员工,薪水1200
60 insert into emp(empno,ename,sal) values(1111,'T_IM',1200);
61 ===============================================================
62 -- 16、查询员工姓名中含有'_'的员工,使用\转义符,让其后的字符回归本来意思【like '%\_%' escape '\'】
63 select * from emp where ename like '%\_%' escape '\';
64 ===============================================================
65 -- 17、插入一个姓名叫'的员工
66 insert into emp(empno,ename) values(2222,'''');
67 -- Oracle中,字符型和日期型都是用单引号,别名才是用双引号。这里,边缘的两单引号是引着字符串'',而里面的两个单引号转义成一个'了。
68 ===============================================================
69 -- 18、插入一个姓名叫''的员工
70 insert into emp(empno,ename) values(2222,'''''');
71 ===============================================================
72 -- 19、查询所有员工信息,使用%或%%
73 select * from emp;
74 select * from emp where ename like '%';
75 select * from emp where ename like '%_%';
76 ===============================================================
77 -- 20、查询佣金为null的员工
78 select * from emp where com is null;
79 -- 注意:null不能与具体数值运算,但能与number/date/varchar2类型运算
80 ===============================================================
81 -- 21、查询佣金为非null的员工
82 select * from emp where comm is not null;
83 ===============================================================
84 -- 22、查询无佣金且工资大于1500的员工
85 select * from emp where (comm is null) and (sal>1500); 
86 ===============================================================
87 -- 23、查询工资是1500或3000或5000的员工 
88 select * from emp where sal in (1500,3000,5000);
89 ===============================================================
90 -- 24、查询职位是"MANAGER"或职位不是"ANALYST"的员工【方式一:使用 != 或 <>。方式二:使用not。】
91 select * from emp where (job='MANAGER') or (job<>'ANALYST');
92 select * from emp where (job='MANAGER') or (not(job='ANALYST'));
93 

3、【命令行】order by 子句

 1 ------------------------  order by子句 ------------------------
 2 
 3 -- 1、查询员工信息(编号,姓名,月薪,年薪),按月薪升序排序,默认升序,如果月薪相同,按oracle内置的校验规则排序
 4 select empno,ename,sal,sal*12 
 5 from emp 
 6 order by sal asc;
 7 ===============================================================
 8 -- 2、查询员工信息(编号,姓名,月薪,年薪),按月薪降序排序
 9 select empno,ename,sal,sal*12 
10 from emp 
11 order by sal desc; 
12 ===============================================================
13 -- 3、查询员工信息,其中,查询年薪,并按入职日期降序排序
14 select empno,ename,sal,hiredate,sal*12 "年薪" 
15 from emp
16 order by hiredate desc;
17 ===============================================================
18 -- 4、order by后面可以跟列名、别名、表达式、列号(在select子句中的列号是从1开始)
19 -- 列名:
20       select empno,ename,sal,hiredate,sal*12 "年薪" 
21       from emp
22       order by hiredate desc;
23 
24 -- 别名:
25       select empno,ename,sal,hiredate,sal*12 "年薪" 
26       from emp
27       order by "年薪" desc;
28 
29 -- 表达式:
30       select empno,ename,sal,hiredate,sal*12 "年薪" 
31       from emp
32       order by sal*12 desc;
33 
34 -- 列号,从1开始:
35       select empno,ename,sal,hiredate,sal*12 "年薪" 
36       from emp
37       order by 5 desc;
38 ===============================================================
39 -- 5、查询员工信息,对有佣金的员工,按佣金降序排列,当order by 和 where 同时出现时,order by 在最后
40 select *
41 from emp
42 where comm is not null
43 order by comm desc;
44 ===============================================================
45 -- 6、查询员工信息,按工资降序排列,相同工资的员工再按入职时间降序排列
46 select *
47 from emp
48 order by sal desc,hiredate desc;
49 -- 注意:只有当sal相同的情况下,hiredate排序才有作用
50 ===============================================================
51 -- 7、查询20号部门,且工资大于1500,并按入职时间降序排列
52 select *
53 from emp
54 where (deptno=20) and (sal>1500)
55 order by hiredate desc;
56 

4、【命令行】单行函数

 1 ------------------------  单行函数 ------------------------
 2 
 3 -- 单行函数:只有一个参数输入,只有一个结果输出
 4 -- 多行函数或分组函数:可有多个参数输入,只有一个结果输出
 5 ===============================================================
 6 -- 1、测试lower/upper/initcap函数。使用dual哑表
 7 select lower('www.BAIdu.COM') as lower from dual; -- 返回值:www.baidu.com
 8 select upper('www.BAIdu.COM') as upper from dual; -- 返回值:WWW.BAIDU.COM
 9 select initcap('www.BAIdu.COM') as initcap from dual; -- 返回值:Www.Baidu.Com  //符号前面的首字母大写
10 ===============================================================
11 -- 2、测试concat/substr函数。从1开始,表示字符,不论中英文
12 select concat('hello','你好') from dual;  -- 返回值:hello你好  //concat(a,b),只能跟两个参数
13 select '你好' || '世界' || 'hello' from dual; -- 返回值:你好世界hello
14 select concat(concat('你好','世界'),'hello') from dual; -- 返回值:你好世界hello
15 
16 select substr('hello你好',5,3) from dual; -- 返回值:o你好 //5表示从第几个字符开始算,第一个字符为1(不是0),中英文统一处理,3表示连续截取多少个字符。
17 -- 不同于java的substring(string,m,n),m从0开始(下标),往后截取n个字符。
18 ===============================================================
19 -- 3、测试length/lengthb函数。存储时:编码方式为UTF8、GBK,一个中文占3、2个字节长度,一个英文一个字节
20 select length('hello你好') from dual; -- 返回值:7  //length()是一个长度的概念,长度为7。
21 select lengthb('hello你好') from dual; -- 返回值:9  //lengthb()是一个大小的概念,9个字节。
22 ===============================================================
23 -- 4、测试instr/lpad/rpad函数
24 select instr('helloworld','o') from dual; -- 返回值:5 //从左向右找 o 第一次出现的位置。从1开始(不是0)
25 select lpad('hello',10,'*') from dual; -- 返回值:*****hello  //lpad(字段,总的大小,添充字符)左填充,即向右对齐
26 select rpad('hello',10,'#') from dual; -- 返回值:hello#####  //rpad(字段,总的大小,添充字符)右填充,即向左对齐
27 -- lpad()和rpad()函数:当第二个参数小于“字段”的总长度时,从左往右截取(截取的长度为第二个参数的大小)
28 ===============================================================
29 -- 5、测试trim/replace函数
30 select trim(' ' from '  he  ll           ') from dual; -- 返回值:he  ll //去掉两边的空格,trim(字符 from 字符串),去掉字符串首尾的指定字符
31 select trim('a' from 'aaabbbbbaaaccccaaaa') from dual; -- 返回值:bbbbbaaacccc //去掉两边的a
32 select replace('hello','l','L') from dual; -- 返回值:heLLo //字符替换
33 ===============================================================
34 -- 6、测试round/trunc/mod函数
35 select round(123.52,0) from dual; -- 返回值:124 //round(数字,从第几未开始截取),并且四舍五入
36 select round(-123.52,0) from dual; -- 返回值:-124
37 select round(123.52,1) from dual; -- 返回值:123.5
38 select round(123.52,-1) from dual; -- 返回值:120
39 select round(123.52,-2) from dual; -- 返回值:100
40 select round(-123.52,-2) from dual; -- 返回值:-100
41 
42 select trunc(123.99,1) from dual; -- 返回值:123.9 //trunc(数字,从第几位开始切),切数字,不存在四舍五入的问题
43 select trunc(-123.99,1) from dual; -- 返回值:-123.9
44 select trunc(123.99,-1) from dual; -- 返回值:120
45 select trunc(-123.99,-1) from dual; -- 返回值:-120
46 select trunc(123.99) from dual; -- 返回值:123
47 
48 select mod(10,3) from dual; -- 返回值:1 //mod(被除数,除数),取余数。注意:Oracle不支持%作为求余符号使用(10%3 会报错)
49 ===============================================================
50 -- 7、日期相关函数
51 select sysdate from dual; -- 返回值:22-3月 -18 //当前系统时间
52 -- round()函数作用于日期型month和year
53 select round(sysdate,'month') from dual; -- 返回值:01-3月 -18 //按照月取系统时间,返回当前月的第一天
54 select round(sysdate,'year') from dual; -- 返回值:01-1月 -18 //按照年取系统时间,返回当前年的第一天
55 -- trunc()函数作用于日期型month和year
56 select trunc(sysdate,'month') from dual; -- 返回值:01-3月 -18 //按照月取系统时间,返回当前月的第一天
57 select trunc(sysdate,'year') from dual; -- 返回值:01-1月 -18 //按照年取系统时间,返回当前年的第一天
58 ===============================================================
59 -- 8、显示昨天,今天,明天的日期;日期类型 +- 数值 = 日期类型
60 select sysdate-1 as "昨天",sysdate as "今天",sysdate+1 as "明天" from dual;
61 ===============================================================
62 -- 9、以年和月的形式显示员工的近似工龄,日期-日期=数值,假设:一年以365天计算,一月以30天计算
63 select ename "姓名",round(sysdate-hiredate,0)/365 "工龄(年)" from emp;
64 ===============================================================
65 -- 10、months_between()函数
66 select months_between('31-12月-18',sysdate) from dual; -- 精确计算到年底还有多少个月
67 select ename "姓名",months_between(sysdate,hiredate) "工龄(月)" from emp; -- 以精确月份的形式,显示员工的工龄
68 ===============================================================
69 -- 11、add_months(date,number)函数
70 select sysdate from dual; -- 返回值:22-3月 -18 //当前系统时间
71 select add_months(sysdate,1) from dual; -- 返回值:22-4月 -18 //下个月今天是多少号
72 select add_months(sysdate,-1) from dual; -- 返回值:22-2月 -18 //上个月今天是多少号
73 ===============================================================
74 -- 12、next_da(date,char)函数。返回date指定的日期之后并满足char指定条件的第一个日期
75 select next_day(sysdate,'星期三') from dual; -- 从今天开始算,下一个星期三是多少号
76 select next_day(next_day(sysdate,'星期三'),'星期三') from dual; -- 从今天开始算,下下一个星期三是多少号
77 select next_day(next_day(sysdate,'星期三'),'星期日') from dual; -- 从今天开始算,下一个星期三的下一个星期日是多少号
78 ===============================================================
79 -- 13、last_day(date)函数;求出该日期的最后一天
80 select last_day(sysdate) from dual; -- 查询本月最后一天是多少号
81 select last_day(sysdate)-1 from dual; -- 查询本月倒数第二天是多少号
82 select last_day(add_months(sysdate,1)) from dual; -- 查询下一个月的最后一天是多少号
83 select last_day(add_months(sysdate,-1)) from dual; -- 查询上一个月的最后一天是多少号
84 ===============================================================
85 注意:
86   1)日期-日期=天数(number)
87   2)日期+-天数=日期
88

5、【命令行】隐式转换

 1 ------------------------  隐式转换 ------------------------
 2 
 3 -- 1、oracle中三大类型与隐式数据类型转换
 4 1)varchar2变长/char定长 ---> number  -- 例如:'123'--->123
 5 2)number ---> varchar2/char  -- 例如:123--->'123'
 6 3)varchar2/char ---> date  -- 例如:'25-4月-15'--->'25-4月-15'
 7 4)date ---> varchar2/char  -- 例如:'25-4月-15'--->'25-4月-15'
 8 5)date和number之间不能相互转换。
 9 ===============================================================
10 -- 2、oracle如何隐式转换:
11 1)=号两边的类型是否相同
12 2)如果=号两边的类型不同,尝试的去做转换
13 3)在转换时,要确保合法合理,否则转换会失败。 -- 例如:12月不会有32天,一年中不会有13月
14 ===============================================================
15 -- 3、案例分析
16    -- 3.1、查询emp表1980年12月17日入职的员工(方式一:日期隐示式转换)
17    select * from emp where hiredate = '17-12月-80'; -- 返回值:7369  SMITH  CLERK  7902  17-12月-80   800    20
18    
19    -- 3.2、使用to_char(日期,'格"常量"式')函数将日期转成字符串
20    select to_char(sysdate,'yyyy" 年 "mm" 月 "dd" 日 "day') from dual; -- 返回值:2018 年 03 月 22 日 星期三
21    
22    -- 3.3、使用to_char(日期,'格式')函数将日期转成字符串
23    select to_char(sysdate,'yyyy-mm-dd" 今天是"day hh24:mi:ss') from dual; -- 返回值:2018-03-22 今天是星期三 15:42:05
24    -- 或者   -- Oracle中的日期格式大小写不敏感(YYYY-MM-DD HH:MI:SS 或者yyyy-mm-dd hh:mi:ss 都行,其中hh24是24小时制)
25    select to_char(sysdate,'yyyy-mm-dd" 今天是"day HH12:MI:SS AM') from dual; -- 返回值:2018-03-22 今天是星期三 03:43:32 下午
26    
27    -- 3.4、使用to_char(数值,'格式')函数将数值转成字符串
28    select to_char(1234567,'$9,999,999') from dual; -- 返回值:$1,234,567
29    
30    -- 3.5、使用to_char(数值,'格式')函数将数值转成字符串,显示如下格式:¥1,234
31    select to_char(1234,'$9,999') from dual; -- 返回值:$1,234
32    select to_char(1234,'L9,999') from dual; -- 返回值:¥1,234
33    
34    -- 3.6、使用to_date('字符串','格式')函数,查询emp表1980年12月17日入职的员工(方式二:日期显式转换)
35    select * from emp where hiredate = to_date('1980年12月17日','yyyy"年"mm"月"dd"日"'); -- 返回值:7369  SMITH  CLERK  7902   17-12月-80   800   20
36    -- 或  -- 只要to_date()函数中的两个参数的格式对应上就好
37    select * from emp where hiredate = to_date('1980#12#17','yyyy"#"mm"#"dd'); -- 返回值:7369  SMITH  CLERK  7902   17-12月-80   800  20
38    --
39    select * from emp where hiredate = to_date('1980-12-17','yyyy-mm-dd'); -- 返回值: 7369  SMITH  CLERK  7902   17-12月-80   800   20
40    
41    -- 3.7、使用to_number('字符串')函数将字符串‘123’转成数字123。这里的字符串只能包括数字
42    select to_number('123') from dual; -- 返回值:123
43    -- 注意:
44       select '123' + 123 from dual; -- 返回值:246
45       select '123' || 123 from dual; -- 返回值:123123  -- 123123是varchar2类型,即:‘123123’
46 ===============================================================

6、【命令行】通用函数和条件判断

 1 ------------------------  通用函数和条件判断 ------------------------
 2 
 3 -- 1、使用nvl(a,b)通用函数,统计员工年收入。 通用函数:参数类型可以是number或varchar2或date类型
 4 select ename,sal*12+NVL(comm,0) from emp;
 5 ===============================================================
 6 -- 2、使用nvl2(a,b,c)通用函数,如果a不为NULL,取b值,否则取c值,统计员工年收入 
 7 select ename,sal*12+NVL2(comm,comm,0) from emp;
 8 ===============================================================
 9 -- 3、使用nullif(a,b)通用函数,在类型一致的情况下,如果a与b相等,返回NULL,否则返回a,比较10和10.0是否相同
10 select nullif(10,10.0) from dual; -- 返回值:  空白,什么都没有
11 select nullif(10,10) from dual; -- 返回值:  空白,什么都没有
12 select NULLIF(10,12) from dual; -- 返回值:10
13 select NULLIF(10,'10') from dual; -- 错误,类型不一致
14 ===============================================================
15 /* 4、case 表达式
16     使用SQL99标准通用语法中的case表达式,将职位是分析员的,工资加2000;职位是经理的,工资加10000;其它职位,工资加600
17         case 字段 
18            when 条件1 then 表达式1
19            when 条件2 then 表达式2
20            else 表达式n
21         end 
22 */
23 select ename "姓名",job "职位",sal "涨前工资",
24     case job 
25         when 'ANALYST' then sal+2000 
26         when 'MANAGER' then sal+10000 
27         else sal+600 
28     end "涨后工资" 
29 from emp; 
30 /*
31 返回值:
32       姓名       职位        涨前工资   涨后工资
33       ---------- --------- ---------- ----------
34       SMITH      CLERK            800       1200
35       ALLEN      SALESMAN        1600       2000
36       WARD       SALESMAN        1250       1650
37       JONES      MANAGER         2975      12975
38       MARTIN     SALESMAN        1250       1650
39       BLAKE      MANAGER         2850      12850
40       CLARK      MANAGER         2450      12450
41       SCOTT      ANALYST         3000       5000
42       ...
43  */
44 ===============================================================
45 /*5、decode()函数
46     使用oracle专用语法中的decode()函数,职位是分析员的,工资加2000;职位是经理的,工资加10000;职位是其它的,工资加600
47        decode(字段,条件1,表达式1,条件2,表达式2,...表达式n)
48 */
49 select ename "姓名",job "职位",sal "涨前工资",
50 decode(job,'ANALYST',sal+2000,'MANAGER',sal+10000,sal+600) "涨后工资"
51 from emp;  -- 返回值:和上面的case表达式的结果一样;但是,比case表达式更简洁。
52 ===============================================================

7、【命令行】多行函数、group by 子句

  1 ------------------------  多行函数 ------------------------
  2 
  3  函数:oracle服务器事先写好的一段具有一定功能的程序片段,内置于oracle服务器,供用户调用 
  4     单行函数:输入一个参数,输出一个结果。
  5     多行函数:输入多个参数,或者是内部扫描多次,输出一个结果。
  6 ===============================================================
  7 -- 1、count()函数
  8    -- 1.1、统计emp表中员工总人数
  9    select count(*) from emp; -- 返回值:14 //即:该表中一共有14数据
 10    -- 注意:*号适用于表字段较少的情况,如果字段较多,扫描时间就会长,效率低,项目中提倡使用某一个非null唯一的字段,通常是主键 
 11    
 12    -- 1.2、统计公司有多少个不重复的部门
 13    select count(distinct deptno) from emp; -- 返回值:3
 14    
 15    -- 1.3、统计有佣金的员工人数
 16    select count(comm) from emp; -- 返回值:4
 17    select concat(count(comm),'') from emp; -- 返回值:4名
 18 ===============================================================
 19 -- 2、sum()函数、avg()函数。 avg全称:average
 20    -- 2.1、员工总工资,平均工资,四舍五入,保留小数点后0位
 21    select sum(sal) "总工资",round(avg(sal),0) "平均工资" from emp;
 22    /*
 23     返回值:
 24         总工资   平均工资
 25       --------  ---------
 26          29025       2073
 27     */
 28 ===============================================================
 29 -- 3、max()、min()函数
 30    -- 3.1、查询员工表中最高工资、最低工资
 31    select max(sal) "最高工资",min(sal) "最低工资" from emp;
 32    
 33    -- 3.2、查询员工表中,入职最早,入职最晚的员工
 34    select max(hiredate) "最晚入职时间",min(hiredate) "最早入职时间" from emp;
 35 ===============================================================
 36 -- 4、group by
 37    -- 4.1、按部门求出该部门平均工资,且平均工资取整数,采用截断
 38    select deptno "部门编号",trunc(avg(sal),0) "部门平均工资"
 39    from emp
 40    group by deptno;
 41    /*
 42     返回值:
 43       部门编号 部门平均工资
 44     ---------- ------------
 45             30         1566
 46             20         2175
 47             10         2916
 48     */
 49     
 50     -- 4.2、查询部门平均工资大于2000元的部门
 51    select deptno "部门编号",trunc(avg(sal),0) "部门平均工资"
 52    from emp
 53    group by deptno
 54    having trunc(avg(sal),0) > 2000; 
 55 
 56    -- 4.3、按部门平均工资降序排列
 57    select deptno "部门编号",trunc(avg(sal),0) "部门平均工资"
 58    from emp
 59    group by deptno
 60    having trunc(avg(sal),0) > 2000
 61    order by 2 desc; -- 2代表列号,第二2列,即:“部门平均工资”
 62 
 63    -- 4.4.1、除10号部门外,查询部门平均工资大于2000元的部门,方式一【having deptno <> 10】
 64    select deptno,avg(sal) from emp
 65    group by deptno
 66    having avg(sal) > 2000 
 67    and deptno <> 10;
 68    
 69    -- 4.4.2、除10号部门外,查询部门平均工资大于2000元的部门,方式二【where deptno<>10】
 70    select deptno,avg(sal) from emp
 71    where deptno <> 10
 72    group by deptno
 73    having avg(sal) > 2000; -- 推荐使用这种
 74 
 75    -- 4.5、显示部门平均工资的最大值
 76    select max(avg(sal)) "部门平均工资的最大值"
 77    from emp
 78    group by deptno;
 79 
 80    /*
 81     group by 子句的细节:
 82        1)在select子句中出现的非多行函数的所有列,【必须】出现在group by子句中.
 83            select deptno,job,avg(sal) from emp; -- 出错;因为avg()是多行函数,必须使用group by分组。
 84            select deptno,job,avg(sal) from emp group by deptno; -- 出错; 因为deptno、job这两个字段都是非多行函数的所有列,所以这两个字段都必须在group by子句中。
 85            select deptno,job,avg(sal) from emp group by deptno,job; -- 正确
 86            
 87        2)在group by子句中出现的所有列,【可出现可不现】在select子句中
 88            select deptno,avg(sal) from emp group by deptno,job; -- 正确;group by子句中有job,select字句中,可写上job,也可以不写。
 89            select deptno,job,avg(sal) from emp group by deptno,job; -- 正确
 90     */
 91     
 92     /*
 93     where和having的区别:
 94         where:
 95            1)行过滤器
 96            2)针对原始的记录
 97            3)跟在from后面
 98            4)where可省
 99            5)先执行
100         
101         having:
102            1)组过滤器
103            2)针对分组后的记录
104            3)跟在group by后面
105            4)having可省
106            5)后执行     
107      */
108      
109      /*
110       oracle中综合语法:
111         1)select子句-----必须
112         2)from子句-------必须,不知写什么表了,就写dual
113         3)where子句------可选
114         4)group by子句---可选
115         5)having子句-----可选
116         6)order by 子句--可选,如果出现列名,别名,表达式,字段
117       */
118 ===============================================================

8、【命令行】多表查询

 1 ------------------------  多表查询  ------------------------
 2 
 3 -- 1、员工表emp和部门表dept的笛卡尔集(笛卡尔集表等于列数之和,行数之积;笛卡尔集表内,有些数据是不符合要求的)
 4 select emp.ename,dept.dname from emp,dept;
 5 -- 或者
 6 select e.ename,d.dname from emp e,dept d;
 7 -- 或者
 8 select ename,dname from emp,dept; -- 只要你查询的字段在对方表中没有(唯一),就不需要e打点/d打点指定
 9 ===============================================================
10 -- 2、使用等值连接/内连接(只能使用=号),显示员工的编号,姓名,部门名,使用表别名简化
11 select e.empno,e.ename,d.dname,d.deptno
12 from emp e,dept d 
13 where e.deptno = d.deptno; 
14 ===============================================================
15 -- 3、使用非等值连接(不能使用=号,其它符号可以,例如:>=,<=,<>,betwen and等),显示员工的编号,姓名,月薪,工资级别
16 select e.empno,e.ename,e.sal,s.grade
17 from emp e,salgrade s
18 where e.sal between s.losal and s.hisal;
19 
20 /* 内连接查询:只能查询出符合条件的记录
21    外连接查询:既能查询出符合条件的记录,也能根据一方强行将另一个方查询出来
22 
23 使用外连接,按部门10,20,30,40号,统计各部门员工人数,要求显示部门号,部门名,人数
24 比如:
25   部门号 部门名      人数
26   10     ACCOUNTING     3 
27   20     RESEARCH       5
28   30     SALES          6
29   40     OPERATIONS     0  -- 这个部门没有人的话,number类型就用0代替,varchar2类型就用null代替
30  */
31 ===============================================================
32 -- 4、使用外连接,按部门10,20,30号,统计各部门员工人数,要求显示部门号,部门名,人数
33 select d.deptno,d.dname,count(e.empno) as "人数"
34 from emp e,dept d
35 where e.deptno(+) = d.deptno
36 group by d.deptno,d.dname;  -- 右外连接
37 /*
38   返回值:
39     DEPTNO DNAME                人数
40     ------ -------------- ----------
41         10 ACCOUNTING              3
42         40 OPERATIONS              0
43         20 RESEARCH                5
44         30 SALES                   6
45  */
46 ===============================================================
47 -- 5、左外连接。 [是oracle专用的,不是SQL99规则]:
48 select d.deptno,d.dname,count(e.empno)
49 from emp e,dept d
50 where e.deptno = d.deptno(+)
51 group by d.deptno,d.dname;
52 ===============================================================
53 -- 6、右外连接。
54 select d.deptno,d.dname,count(e.empno)
55 from emp e,dept d
56 where e.deptno(+) = d.deptno
57 group by d.deptno,d.dname;
58 ===============================================================
59 -- 7、使用左外连接,按部门10,20,30,40号,统计各部门员工人数,要求显示部门号,部门名,人数,且按人数降序排列
60 select dept.deptno "部门号",dept.dname "部门名",count(emp.empno) "人数"
61 from dept,emp
62 where dept.deptno = emp.deptno(+) 
63 group by dept.deptno,dept.dname
64 order by 3 desc;  -- 3代表:以第三列“人数”作降序排列
65 ===============================================================
66 -- 8、使用自连接,显示"SMITH的上级是FORD",这种格式
67 select users.ename || '的上级是' ||boss.ename
68 from emp users,emp boss
69 where users.mgr = boss.empno;  -- mgr是上级编号,empno是员工编号
70 ===============================================================
71 -- 9、基于上述问题(第八点),将KING的上级是“”显示出来
72 select users.ename || '的上级是' ||boss.ename
73 from emp users,emp boss
74 where users.mgr = boss.empno(+); -- KING 是老板
75 -- 注意:自连接有时候也需要用到内连接和外连接
76 ===============================================================

9、【命令行】子查询

 1 ------------------------  子查询  ------------------------
 2 
 3 /*
 4    子查询的作用:查询条件未知的事物
 5 
 6    查询条件已知的问题:例如:查询工资为800的员工信息
 7    查询条件未知的问题:例如:查询工资为20号部门平均工资的员工信息
 8    一个条件未知的问题:可以分解为多个条件已知的问题
 9    
10    子查询细节:
11         1)子查询与父查询可以针对同一张表 
12         2)子查询与父查询可以针对不同张表
13         3) 子查询与父查询在传参数时,数量要相同
14         4) 子查询与父查询在传参数时,类型要相同
15         5) 子查询与父查询在传参数时,含义要相同
16 */
17 ===============================================================
18 -- 1、查询工资比WARD高的员工信息
19    -- 第一:查询WARD的工资?
20    select sal from emp where ename = 'WARD';
21    -- 第二:查询工资比1250高的员工信息?
22    select * from emp where sal > 1250;
23 
24    -- 子查询:
25    select * from emp where sal > (
26                                    select sal 
27                                    from emp 
28                                    where ename = 'WARD'
29                                  );
30 ===============================================================
31 -- 2、查询部门名为'SALES'的员工信息(方式一:子查询)
32    -- 第一:查询部门名为'SALES'的编号?
33    select deptno from dept where dname = 'SALES';
34    -- 第二:查询部门号为30的员工信息? 
35    select * from emp where deptno = 30;
36       
37 -- 子查询:
38    select * 
39    from emp 
40    where deptno = (
41         select deptno 
42         from dept 
43         where dname = 'SALES'
44    );
45 ===============================================================
46 -- 3、查询部门名为'SALES'的员工信息(方式二:多表查询)
47 select emp.*
48 from dept,emp
49 where (dept.deptno=emp.deptno) and (dept.dname='SALES'); 
50 
51 -- 查询每个员工编号,姓名,部门名,工资等级(三表查询,这三张表并无外健关联)
52 select e.empno,e.ename,d.dname,s.grade
53 from emp e,dept d,salgrade s
54 where (e.deptno=d.deptno) and (e.sal between s.losal and s.hisal);
55 ===============================================================
56 -- 4、查询工资最低的员工信息。(单行子查询,使用=号)
57 select * 
58 from emp 
59 where sal = (
60     select min(sal) 
61     from emp
62 );
63 ===============================================================
64 -- 5、查询部门名为'ACCOUNTING'或'SALES'的员工信息。(多行子查询,使用in关键字)    
65 select * 
66 from emp 
67 where deptno in (
68     select deptno 
69     from dept 
70     where dname in ('ACCOUNTING','SALES')
71 );
72 ===============================================================
73 -- 6、查询工资比20号部门【任意any】一个员工工资【低<】的员工信息。(多行子查询,使用any关键字) 
74 select * 
75 from emp 
76 where sal < any (
77     select sal 
78     from emp 
79     where deptno = 20
80 ); 
81 ===============================================================
82 -- 7、查询工资比30号部门【所有all】员工【低<】的员工信息。(多行子查询,使用all关键字) 
83 select * 
84 from emp 
85 where sal < all (
86     select sal 
87     from emp 
88     where deptno = 30
89 );
90 /*
91   单行子查询:子查询只会返回一个结果,例如:800,父查询用 =、<>、>=、<= 这些符号来比较
92   多行子查询:子查询会返回多于一个结果,例如:30,20,父查询用 in、any、all 这些符号来比较
93 */
94 ===============================================================

10、【命令行】集合查询

 1 ------------------------  集合查询  ------------------------
 2 
 3 -- 1、使用并集运算,查询20号部门或30号部门的员工信息
 4 select * from emp where deptno = 20
 5 union
 6 select * from emp where deptno = 30;
 7 /*
 8 注意:
 9     union:二个集合中,如果都有相同的,取其一
10     union all:二个集合中,如果都有相同的,都取
11     取并集时,两个子表的结构(字段含义及其顺序)必须完全一致。
12       select * from emp 
13       union 
14       select * from copy_emp; -- emp表和copy_emp表的结构、表内的数据一模一样。唯一不同的是copy_emp表插入了一条数据 用于作并集查询时,体现不同之处。
15 */
16 ===============================================================
17 -- 2、使用交集运算[intersect]
18    -- 2.1、查询工资在1000-2000和1500-2500之间的员工信息(方式一)
19    select * from emp where sal between 1000 and 2000
20    intersect
21    select * from emp where sal between 1500 and 2500; -- 即:1500到2000之间的
22 
23    -- 2.2、用where行过滤,查询工资在1000-2000和1500-2500之间的员工信息(方式二)
24    select * 
25    from emp
26    where (sal between 1000 and 2000) and (sal between 1500 and 2500);
27 ===============================================================
28 -- 3、使用差集运算[minus]
29    -- A-B = A-AnB
30    -- 3.1、查询工资在1000-2000,但不在1500-2500之间的员工信息(方式一)
31    select * from emp where sal between 1000 and 2000
32    minus
33    select * from emp where sal between 1500 and 2500;
34 
35    -- 3.2、使用where行过滤,查询工资在1000-2000,但不在1500-2500之间的员工信息(方式二)
36    select * 
37    from emp 
38    where (sal between 1000 and 2000) and (sal not between 1500 and 2500);
39 ===============================================================
40 -- 4、集合查询的细节:
41    -- 4.1、集合操作时,必须确保集合列数是相等
42    select empno,ename,sal,comm from emp where deptno = 20 -- 多了一列,和下面的查询 列数不相等
43    union
44    select empno,ename,sal from emp where deptno = 30; --
45 
46    -- 4.2、集合操作时,必须确保集合列类型对应相同
47    select empno,ename,sal,comm from emp where deptno = 20  -- 两条语句,列数相等,但是,类型不相等,comm是number类型,hiredate是date类型
48    union
49    select empno,ename,sal,hiredate from emp where deptno = 30; --
50 
51    -- 4.3、A union B union C = C union B union A
52    -- Union的两个子表的先后顺序不影响结果(顺序可能不一致)
53    select * from emp where deptno = 10
54    union
55    select * from emp where deptno = 20
56    union
57    select * from emp where deptno = 30;
58 
59    -- 4.4、当多个集合操作时,结果的列名由第一个集合列名决定
60    select empno "编号",ename "姓名",sal "薪水" from emp where deptno = 20
61    union
62    select empno,ename,sal from emp where deptno = 10;
63 /*
64   当多表查询,子查询,集合查询都能完成同样任务时,按如下优化方案选择:
65   多表查询--->子查询--->集合查询
66 */
67 ===============================================================

11、【命令行】Oracle分页(分页查询)

 1 ------------------------  分页查询  ------------------------
 2 
 3 -- 1、什么是rownum,有何特点
 4    -- 1)rownum是oracle专用的关健字
 5    -- 2)rownum与表在一起,表亡它亡,表在它在 
 6    -- 3)rownum在默认情况下,从表中是查不出来的
 7    -- 4)只有在select子句中,明确写出rownum才能显示出来,从1开始
 8    -- 5)rownum是number类型,且唯一连续
 9    -- 6)rownum最小值是1,最大值与你的记录条数相同
10    /* 7)rownum也能参与关系运算
11         rownum = 1    有值
12         rownum < 5    有值    
13         rownum <=5    有值         
14         rownum > 2    无值        
15         rownum >=2    无值
16         rownum <>2    有值    与  rownum < 2 相同
17         rownum = 2    无值
18    */
19    -- 8)基于rownum的特性,我们通常rownum只用于 < 或 <= 关系运算
20 ===============================================================
21 -- 2、显示emp表中3-8条记录(方式一:使用集合减运算)
22 select rownum "伪列",emp.* from emp where rownum <= 8
23 minus
24 select rownum,emp.* from emp where rownum <= 2;
25 ===============================================================
26 -- 3、显示emp表中3-8条记录(方式二:使用子查询,在from子句中使用,重点)
27 select xx.*
28 from (select rownum as ids,emp.* from emp where rownum <= 8) xx 
29 where ids > 2;
30 -- 注意:在子查询中的别名,不可加""引号
31 ===============================================================
32 -- 4、显示emp表中5-9条记录
33 select yy.*
34 from (select rownum as ids,emp.* from emp where rownum <=9 ) yy
35 where ids >= 5;
36 -- 注意:在项目中,from后台可能有真实表名,也可能用子查询看作的表名,同时真实表和子查询看作的表要做连接查询
37 ===============================================================
38 -- 5、MySQL分页  使用关键字:limit
39    -- 每页显示10条数据,查询第一页和第二页的数据
40    select * from 表名称 limit 0,10; -- 第一页,第1到第10条数据。
41    select * from 表名称 limit 10,20; -- 第二页,第11到第20条数据。注意:MySQL 是从0开始(下标)
42 ===============================================================

12、【命令行】约束和表、表结构、表内数据的CRUD操作

  1 ------------------------  约束、表、表结构和表内数据的CRUD操作  ------------------------
  2 
  3 /*
  4   Oracle的五大约束条件:
  5     a、主键  primary key
  6     b、外键  foreign key,
  7     c、唯一  unique,
  8     d、检测  check
  9     e、非空  not null
 10 */
 11 
 12 -- 1、对数据的CRUD操作
 13    -- 1.1、创建用户表users(id整型/name字符串/birthday日期/sal整型,默认今天)
 14    create table users(
 15      id number(5) primary key,
 16      name varchar2(8) not null unique,
 17      sal number(6,2) not null,
 18      birthday date default sysdate
 19    );
 20    -- 创建序列
 21    create sequence users_seq; -- 由于Oracle没有自增一说,所以要借助序列来实现自增长。(这里只是简单演示,所以序列也就简单的创建)
 22 ===============================================================
 23    -- 1.2、删除users表
 24    drop table users; -- 此处的删除users表,并不是真正删除了,而是把users放入了回收站,和window的删除一样
 25 ===============================================================
 26    -- 1.3、查询回收站中的对象
 27    show recyclebin;
 28 ===============================================================
 29    -- 1.4、闪回,即:将回收站删除的对象还原
 30    flashback table 表名 to before drop; -- 还原之前删除的对象
 31    flashback table 表名 to before drop rename to 新表名; -- 还原之前删除的对象,并将它换个新名字
 32 ===============================================================
 33    -- 1.5、彻底删除users表
 34    drop table users purge;
 35 ===============================================================
 36    -- 1.6、清空回收站
 37    purge recyclebin;
 38 ===============================================================
 39    -- 1.7、查询当前用户下所有表
 40    select * from tab; 
 41    -- 1.7.1、查询users表中所有数据
 42    select * from users; 
 43 ===============================================================
 44    -- 1.8、修改表名称。 格式:alter table 原表名 rename to 新表名;
 45    alter table users rename to users2;
 46    /* 
 47       Oracle数据库的常用类型:
 48         number:相当于MySQL/Java中的int类型。
 49         varchar2:相当于MySQL中的varchar类型,Java中的String类型
 50         date:时间类型。默认格式为:'27-5月-18'
 51         CLOB【Character Large OBject】:大文本对象,即超过65565字节的数据对象,最多存储4G
 52         BLOB【Binary Large OBject】:大二进制对象,即图片,音频,视频,最多存储4G
 53     */
 54 ===============================================================
 55 -- 2、对表结构的CRUD操作
 56    -- 2.1、为users表增加image列。 格式:alter table 表名 add 列名 类型(宽度) 
 57    alter table users add image varchar2(20);
 58 ===============================================================
 59    -- 2.2、修改imgae列的长度为30个字节。 格式:alter table 表名 modify 列名 类型(宽度) 
 60    alter table users modify image varchar2(30);
 61 ===============================================================
 62    -- 2.3、删除image列。 格式:alter table 表名 drop column 列名
 63    alter table users drop column image;
 64 ===============================================================
 65    -- 2.4、重名列名image为imagepath。 格式:alter table 表名 rename column 原列名 to 新列名
 66    alter table users rename column image to imagepath;
 67 ===============================================================
 68    -- 2.5、将users表重命名user。 格式:rename 原表名 to 新表名
 69    rename users to new_users;
 70    -- 注意:修改表字段(结构)时,不会影响表中原有的数据
 71 ===============================================================
 72    -- 2.6、查询表结构(字段的详细信息)。 格式:desc 表名称;
 73    desc users;
 74 ===============================================================
 75 -- 3、java连接oracle数据库
 76 private static String driver = "oracle.jdbc.driver.OracleDriver"; //访问oracle服务器的驱动名称
 77 private static String url = "jdbc:oracle:thin:@127.0.0.1:1521:orcl"; //访问oracle服务器的连接字串,其中127.0.0.1可用localhost(本地)代替
 78 private static String username = "scott"; //访问orcl数据库的用户名
 79 private static String password = "tiger"; //访问orcl数据库的密码
 80 ===============================================================
 81 -- 4、表内数据的CRUD操作
 82    /*
 83      SQL92/99标准的四大类:
 84          DML:select、insert、update、delete
 85          DDL:create table、alter table、drop table、truncate table
 86          DCL:grant select any table to scott、revoke select any table from scott
 87          TCL:commit、rollback、savepoint to 回滚点
 88    */
 89    
 90    -- 4.1、添加,向users表中数据。 格式:insert into 表名 values(全部字段); 或者 insert into 表名(个别字段) values(对应的个别字段);
 91    insert into users values(users_seq.nextval,'张三',2000,sysdate); -- sysdate可以不写,因为默认就是sysdate,可上面的建表脚本
 92    -- 或者
 93    insert into users(id,name) values(users_seq.nextval,'李四');
 94    -- 批量插入
 95    insert into users select * from copy_users where sal = 2000; -- 将copy_users表中所有sal=2000元的用户,复制到users表中
 96 ===============================================================
 97    -- 4.2、使用&占位符,动态输入值,&可以运用在任何一个DML语句中,在values子句中使用,例如:'&name'和&sal等
 98    insert into users values(&id,'&name','&sal','&birthday'); -- 回车后,每个值都需要一个一个的输入
 99    -- 注意:&是sqlplus工具提供的占位符,如果是字符串或日期型要加' '符,数值型无需加' '符
100 ===============================================================
101    -- 4.3、使用&占位符,动态输入值,&可以运用在任何一个DML语句中,在from子句中使用
102    select * from &table;
103 ===============================================================
104    -- 4.4、删除users表中的所有记录
105    delete from users;
106    -- 删除无工资的用户
107    delete from users where sal is null;
108 ===============================================================
109    -- 4.5、修改,将'张三'的工资增加20%
110    update users set sal = sal*1.2 where name = upper('张三');
111 ===============================================================
112    -- 4.6查询users表中的所有数据
113    select * from users;
114 
115 /*
116  drop table 和 truncate table 和 delete from 区别:
117     drop table
118        1)属于DDL
119        2)可回滚
120        3)不可带where
121        4)表内容和结构删除
122        5)删除速度快
123 
124     truncate table
125        1)属于DDL
126        2)不可回滚
127        3)不可带where
128        4)表内容删除
129        5)删除速度快
130 
131     delete from
132        1)属于DML
133        2)不可回滚
134        3)可带where
135        4)表结构在,表内容要看where执行的情况
136        5)删除速度慢,需要逐行删除
137 */
138 ===============================================================

13、Oracle事务

1、概念
  什么叫做事务? 答:是不可分割的子操作形成的一个整体,该整体要么全部执行成功,要么全部失败。
  为什么要用事务? 答:如果不使用事务的话,就会出现致命的操作异常。
  事务放在哪一层? 答:业务层

只针对DML(数据操纵语言)操作:selectdeleteupdateinsert
(1)Oracle的事务提交
    显式提交:commit()
    隐藏提交:sqlplus中执行exit、DDL、DCL
    提交——从事务的开始到提交的中间内容、提交到oracle数据库中的DBF二进制文件。

(2)Oracle的事务回滚
    显式回滚:rollback()
    隐藏回滚:死机、断电、关闭窗口(sqlplus工具)

(3)回滚点
    在操作之间设置的一个标志位,用来回滚。
    
(4)回滚点的使用
    savepoint 回滚点
    rollback to savepoint 回滚点

Oracle的事务提交或回滚之后,原来的回滚点已经无效。
Oracle的事务能够回滚,是因为oracle提供了一个实例机制。

2、jdbc 事务

1 try{
2      connection.setAutoCommit(false);//开启事务
3      ......
4      connection.commit();//try的最后提交事务      
5 } catch() {
6     connection.rollback();//回滚事务
7 }

3、Hibernate 事务

4、Spring 事务

  比较经典的是声明式事务管理

  可参考(看下面的实例):https://www.cnblogs.com/myseries/p/10834172.html

5、MySQL 事务

start transaction;

可参考(看下面的实例):https://www.cnblogs.com/develop-SZT/p/10339138.html

6、事务的隔离级别

  6.1、MySQL 的隔离级别

  6.2、Oracle中支持Read Committed(默认)和Serializable两种。
      设置隔离级别的方法:set transaction isolation level serializable;

可这样演示:两个用户同时删除emp表中的’SISI’这个员工信息,会有什么后果?
    答:只有一个用户会删除成功,在先操作的用户,还没有提交的情况下,另外一个用户只能等待。

14、Oracle 视图

  1、概念

      视图是一个虚表;视图建立在已有的表基础,视图赖以建立的这个数据表称为基表。
      向视图提供数据内容使用select语句,可以将视图理解为存储起来的select语句。
      视图向用户提供了基表数据的另外一个表现形式。
      视图只是一种逻辑上的概念,并没有存储真正的数据,真正的数据还是存储在基表中。
      程序员对视图的操作,最终还是转换成对基表的操作。
      一个数据表可以没有视图,也可以有一个或多个视图。

  2、使用场景

      不希望用户访问数据表的全部字段或全部数据,只想看到其中的部分价值信息,此时可以使用视图。银行、电信、证券、金属、军事、航天等等领域。
      需要简化sql的查询过程,或提供sql的执行效率时,可以适当使用视图。

  3、视图作用

    a.限制数据访问
    b.简化复杂查询
    c.提供数据的相互独立
    d.同样的数据,以不同的形式显示

  4、视图的简单操作

    (1)创建:
      默认情况下,普通用户没有创建视图的权限。需要由sysdba授予权限:
     (以sysdba的身份登录)grant create view to scott;
      如果想撤销权限:(以sysdba的身份登录)revoke create view from scott;

 1 1)基于emp表的所有列,创建一个视图
 2   create view emp_view_1
 3   as
 4   select * from emp;
 5 2)基于指定列创建视图
 6   create view emp_view_2
 7   as
 8   select ename “姓名”,deptno,sal,sal*12 “年薪” from emp;
 9 3)查询emp表,求出部门的最低工资、最高工资、平均工资,等方式创建视图
10   create view emp_view_3
11   as
12   select deptno “部门”,min(sal) “最低工资”,max(sal) “最高工资”,avg(sal) “平均工资” from emp group by deptno;

  (2)修改:

1 -- 修改emp_view_4(id,name,salary,annual,income)视图。 格式:create or replace view 视图名 as 子查询
2   create or replace view emp_view_4(id,name,salary,annual,income)
3   as
4   select empno "编号",ename "姓名",sal "工资",sal*12 "年薪",sal*12+NVL(comm,0)+100 "年收入"
5   from emp;

  (3)删除:

 1   -- 删除emp_view_4视图中某一条记录(以id=2222为例)
 2   delete from emp_view_4 where id = 2222;
 3   -- 注意:视图默认是可以删除的(readonly=false),如果在创建视图时指定了不可删除(readonly),那么不能执行删除。
 4 
 5   create view emp_view_5(id,name,salary,annual,income)
 6   as
 7   select empno,ename ,sal,sal*12,sal*12+NVL(comm,0)
 8   from emp
 9   with read only; -- 设置了只读
10   -- 此时执行删除delete from emp_view_5 where id=2222会失败。

  5、问答

  Q1:删除视图中(某一条或部分)的记录,是否会影响基表?
    答:会
  Q2:删除视图中的全部记录,是否会影响基表?
    答:会
  Q3:drop(删除)视图时,是否会影响基表?
    答:不会
  Q4:删除视图是否会进入回收站?
    答:不会
  Q5:删除基表,视图是否存在?
    答:不存在
  Q6:删除基表后,通过回收站闪回后,视图是否又存在了?
    答:是

15、Oracle 序列

  1、概念

      类似于与MySQL中的auto increment自增长机制,但是Oracle中无自增长机制。
      Oracle会提供一个产生唯一数(number类型)的机制。
      通常用在表的主键。
      序列保证唯一,但是不保证连续。rownum从1开始,总是连续。
      序列值一般放在内存,取之较快。

  2、为什么不用rownum作为主键?

      答:rownum不能唯一标示某一行。

  3、序列的价值

      为表做主键,唯一标识表中每一条记录。

4、序列的使用

 1   -- 创建序列:create sequence 序列名;
 2   create sequence dept_seq;
 3 
 4   -- 删除序列:drop sequence 序列名;
 5   drop sequence dept_seq;
 6 
 7   -- 查看序列的当前值currval和下一个值nextval。(第一次使用序列时,不能使用currval)
 8   select dept_seq.nextval from dual;
 9   select dept_seq.currval from dual;
10 
11   -- 使用序列往表中插入一条记录。
12   insert into dept values(dept_seq.nextval,’IT’,’XINYU’);
13 
14   -- 修改dept_seq序列increment by 10(步长默认为1),默认start with 1
15   alter sequence dept_seq increment by 10;
16   -- 修改dept_seq序列的start with 2(无法修改)。
17 
18   -- 为某个表设置序列之后,依然能够手工插入主键。
19   insert into dept values(50,’hhhhh’,’nanchang’); 
20 
21   -- 删除表,不影响已经创建的序列。
22   -- 删除序列,不影响表。

序列的详细操作,可参考:https://www.cnblogs.com/dshore123/p/8269537.html

16、Oracle 索引

  1、概念:
      是一种快速查询表内容的机制。运用在表中的某个/某些字段上,但是存储是,独立于表之外。

  2、索引的意义:
      通过指针加速Oracle服务器的查询速度;通过rowid快速定位数据,减少磁盘的I/O,rowid是Oracle中唯一确定每一张表不同记录的唯一身份证。

  3、rowid特点
      位于每个表中,但是表面上看不到。
      只有在select语句中可以查询到。
      rowid与每一张表绑定在一起,如果表已经不存在那么对应的rowid就不存在了;不同的表rowid必须不同/唯一。
      rowid是18位大小的字母和数字组成,唯一代表某一条记录在DBF文件中的位置。
      rowid是联系表和DBF文件的桥梁。

  4、创建索引的场景:
      经常进行select操作时
      表很大(字段多、记录多),表内容分布的范围广
      列名经常在where子句或连接条件中

  5、不需要创建索引的场景:
      表经常进行insert/update/delete操作
      表很小
      列名不经常出现,或很少用于where的连接条件中

6、实例:

 11)单列索引:
 2     -- 为dept表的deptno字段创建一个索引(单列索引):create index 索引名 on 表名(字段)
 3     create index dept_deptno_index on dept(deptno);
 42)多列索引、联合索引
 5     create index deptno_dname_index on dept(deptno,dname);
 6     drop index deptno_dname_index; -- 删除索引
 7     -- 注意:为某个/某些字段创建索引后,根据这个/这些字段查询时,效率会提高。
 8 
 9   -- 查询当前出问题的列是否已经被哪个索引占用了:
10   select * from user_ind_columns where table_name = '你的大写表名'
11   and column_name = '大写字段名';

 

 

 

 

 

 

原创作者:DSHORE

作者主页:http://www.cnblogs.com/dshore123/

原文出自:http://www.cnblogs.com/dshore123/p/8622757.html

版权声明:欢迎转载,转载务必说明出处。(如果本文对您有帮助,可以点击一下右下角的 推荐,或评论,谢谢!

posted @ 2018-03-22 12:06  DSHORE  阅读(1199)  评论(0编辑  收藏  举报