Oracle 串讲
Oracle 总结
Oracle SQL(Oracle 9i 9.2.0.1.0)
SQL(结构化查询语言),是操作关系型数据库中的对象。
DDL(数据定义语言)语句,用于建表或删表操作,以及对表约束进行修改。
DML(数据操作语言)语句,向表中插入纪录,修改纪录。
事务控制语句:commit; rollback;
授权语句
select语句(数据的查询),投影,过滤(选择)查寻,关联查寻(表连接)。
sqlplus 访问数据库命令(本地访问/远程访问),和数据库建立连接的命令,是数据库操作的环境
sqlplus 用户名/密码
show user 显示当前用户的用户名
select查询语句
select table_name from user_tables;(查询系统表)
查询本用户下所拥有的所有表的表名。
desc [表名] 这是一条sqlplus命令,注意他不是sql语句,这条命令用于查看表的结构。
[字段名] [字段的类型]
投影操作,只查看选择的字段的信息。
选择操作,查看字段中的特定某些信息。
多表查询,通过表间连接,查寻出多表中的信息
select 语句中可以使用数学表达式。
select [表达式(必须包含本表字段名)],[...],.... from 表名;
select salary*12 from s_emp;
运算的优先级的先乘除后加减,同级自左向右运算,括号改变优先级。
select [字段名或表达式] ["别名"],[...] ["..."],.... from 表名;
可以通过在字段名或表达式后加空格"别名",可以给列,或者表达式结果其别名。
字符串拼接使用||符号
select salary*12 “total_salary” from s_emp;
select 目标字段名||’ ‘||目标字段名 from 表名;
select first_name||’ salary is ‘||salary from s_emp;
FIRST_NAME||'SALARYIS'||SALARY
-----------------------
Alexander salary is 850
Eddie salary is 800
Radha salary is 795
Bela salary is 860
Sylvie salary is 1100
Roscea salary is
注意:在Oracle中的字符串要用'..'包含,别名中需要使用空格,或是大小写敏感时需要用".."包含。
过滤操作
1、order by 排序子句 ASC(默认,升序) DESC(降序)
order by 目标列名(别名) 排序顺序(不写排序顺序,会默认为升序排序)
例:select first_name from s_emp order by first_name;
select first_name from s_emp order by first_name desc;
注意:升序空值(无穷大)在结果的末尾,降序空值在结果的最前面。
2、where子句
where子句使用在 select ... from ... 后面,用来选择所需(符合条件的)的记录
where后面跟的是表达式(要用列名,不要用别名) : XXX=XXX, XXX between X and X ,XXX in(X,X,X)
3、like '...' 通配查询,常与“%”(0~N个)连用
like '...' 字符串通配查询,'%'表示多个字符,
4、between ... and ... ,表示结果在这之间,between and是一个闭区间,也就相当于... <= ... and ... >= ... 。
!=,<>,^=,这三个都标识不等于,<=,>=,=,这些运算符都可以使用。
... in (va1,val2,...) 判断结果是否在这个枚举中存在
... and ... 表示只有两个条件同时满足
... or ... 表示条件只要满足其中只一就可以
all(数据或子查询)。
例:
select table_name from user_tables where table_name like ‘s\_%’ escape ‘\’;
'_',表示一个字符,'\'转意字符
使用escape定义转义符 'S\_%' escape '\',使用转义,可以避免和运算符相同的字符的查询
select first_name from s_emp where salary<>all(2500,1500);
all中的数据和纪录中的值全部一致,一般使用!=all(),来过滤在某个范围纪录
空值会对not in造成影响,也就是不等于任何值,但是空值例外,即不能是not in null.
... is null 使用来判断值是不是空。
select table_name from user_tables where table_name like 'S\_%' escape '\'
注意:Oracle中的字符串是严格区分大小写的。
Oracle数据库函数(单行函数)
单行函数可以出现在select 后面,也可以出现在where子句中需要处理现实的结果时,就把函数写在select后面,用于条件过滤时,就把函数用在where子句中。
1、控制处理函数 NVL(字段名,值),这个字段中的空值替换为指定值,如果不为空,则会返回其原值。
例:select (salary*12)*(NVL(commission_pct,0)/100+1) salary,first_name
from s_emp;
2、字符函数(varchar)
字符是大小写敏感的
转小写 lower(‘...’)
转大写 upper(‘...’)
首字母大写 initcap(‘...’)
dual表,是专门用于函数测试和运算的,他只有一条记录
字符串拼接 concat(‘...’,’....’)
求指定子串 substr(‘...’,起始位置,取字符个数)(起始位置可以为负)
求制定字符串的长度length(‘……’)
例:
select upper(‘test’) from dual;
select first_name from s_emp where upper(first_name)=’GEORGE’;
select substr(first_name,-2,2) sub from s_emp;(取后两个)
select substr(first_name,2,2) sub from s_emp;(取前两个)
3、数值函数(number)
四舍五入 round(数据,保留小数点后几位)
可以用负数表示小数点前,0,表示小数点后第一位,也就是保留个位,-1表示个位(保留到十 位)。
例:select round(15.36,1) from dual;
结果:15.4
截取数字函数 trunc(数据,保留的位数(小数点后位数)) 截取个位之后补0
例:select trunc(123.456,-1) from dual; 保留倒十位
结果:120
4、日期函数
全日期格式: 世纪信息,年月日,时分秒。
缺省日期格式:日-月-年 dd-mon-rr
日期类型是可以进行数学运算的,+1,是下一天,-1,是上一天,数据库会对数据所隐式的转换。
修改当前会话的日期格式,会按照指定的格式输出日期
alter session set nls_date_format='yyyy mm dd hh24:mi:ss';
返回当前日期 sysdate: select sysdate from dual
例:select sysdate+20 from dual; //20天后的日期
日期是格式敏感的
求两个日期间相隔了多少个月 months_between(date1,date2)
加减指定数量的月份 add_months(date,月数),月数可以为负,负值就是减去相应的月数。
从下周开始的日期加一天 next_day(date,天数)
例:select next_day(sysdate,2) from dual;
返回月末的日期 last_day(date)
截取日期 trunc(date,'年或月或日或时分秒')
例:select trunc(add_months(sysdate,1),'month') from dual;
5、不同数据类型间转换函数
将日期转成字符 to_char(date,'日期格式')
日期格式要用有效格式,格式大小写敏感 'yyyy mm dd hh24:mi:ss','year'(全拼的年),'mm'(数字表示的月) 'month'(全拼的月),'day'(星期的全拼),'ddspth' (日期的全拼) 'yy mm dd',’rr-mm-dd’(会根据年份判断世纪)
例:select to_char(sysdate,'yyyy mm dd hh24:mi:ss') from dual;
select to_char(salary,'fm$9,999,999') from s_emp;
将字符转换成数字 to_number('...'),(可以加第二参数,第二参数指定定数字进制)
select to_char(salary,'fm$9,999,999') from s_emp;
将数字转字符to_char(number,'fmt') fmt是数字格式
select to_number(userid) from s_emp where id=74;
将字符串转成日期 to_date('...','日期格式')
…….. to_date('2006 11 03','yyyy mm dd')……;
5、函数嵌套
例:
select to_char(to_date('2006 11 03','yyyy mm dd'),'dd-month-yy') from dual;
表连接(关联查寻)
等值连接
select [表别名1.字段名1],[表别名2.字段名2],...
from 表1 表别名1 ,表2 表别名2
where 表别名1.字段名3=表别名2.字段名4;
表连接时,表与表之间有同名字段,可以加上表的别名,加以区分,用表名.字段名或表别名.字段名(列名)。表的字段名是唯一,不用加表名.或表的别名。
非等值连接
....可以使比较运算符,也可以使其他的除了'='的运算符
例:select e.ename, d.grade,e.sal
from emp e,salgrade d
where e.sal between d.losal and d.hisal;
自连接
用两个别名把一张表中的数据分成两部分,然后在使用条件过滤。
select [表别名1.字段名1],[表别名2.字段名2],...
from 表1 表别名1 ,表1 表别名2
where 表别名1.字段名3=表别名2.字段名4;
例:select a.first_name ename,b.first_name cname from s_emp a,s_emp b where a.manager_id=b.id;
以上所提到的表连接,都叫做内连接,严格匹配两表的记录。
外连接
外连接会使用一方表中的所有记录去和另一格表中的记录按条件匹配,空值也会匹配,这个表中的所有记录都会显示,数据库会模拟出记录去和那些不匹配的记录匹配。
例:select a.first_name enamei,a.id,b.first_name cname,b.id from s_emp a,s_emp b where a.manager_id=b.id(+);
注意:要把那一方的记录全部都显示出来,还有注意条件(+)跟在要全部显示的那个表的字段后。
group by 分组子句
按指定的分组规则分组 ,这个group by 子句可以跟在 select 语句后或是 having后面。group by子句也会出发排序操作,会按分组字段排序。
select [组函数或分组的字段名] ,... from 表名 group by [字段名1],[字段名2],.....;
例:select avg(salary) from s_emp group by dept_id;
注意:组函数可以处理一组数据,返回一个值。组函数会忽略空值。count()除外,他会把空记录也记录在内。
如果查询语句中有group by子句,select后可跟group by后的字段和组函数(一起出现)。如果没有group by子句,select后不能跟字段和组函数(不能一起出现),此时select后只能单独跟字段(可以多个字段) 或者单独跟组函数(多个组函数)。
组函数
avg(..),求平均值,sum(..),求和 这两个函数的参数只能是number型的。
以下所提到的函数可以使用任意类型做参数。
distinct关键字可以排重。
count(..),用来统计记录数,可以使用排重命令。count(...)默认使用的是all。
max(..),min(..)求最大值和最小值 (排重)
count(*),统计表中记录数。
例:select max(b.name),avg(a.salary), max(c.name) from s_emp a,s_dept b,s_region c where a.dept_id=b.id and b.region_id=c.id group by b.id;
having子句可以过滤组函数结果或是分组后的记录,且写在group by子句后。
例:
select max(b.name),avg(a.salary), max(c.name)
from s_emp a,s_dept b,s_region c
where a.dept_id=b.id and b.region_id=c.id
group by b.id having sum(a.salary)>4000;
注意:要先过滤掉不需要的记录,然后再进行分组操作,提高效率。
where过滤条件是最先执行的。
子查询
子查询,就是可以嵌在任何的sql语句中的select语句。
在select语句中嵌套子查询时,会先执行子查询。一般的会将子查询放在运算符的右边。
注意:在使用子查询时,要注意这个运算符是单行的(也就是只能是单值),还是多行运算符(范围,多值)。配合使用子查询返回的结果必须符合运算符的用法。
例:
select first_name,title from s_emp
where title=any(select title from s_emp where last_name='Smith') and upper(last_name)!='SMITH';
约束
约束是针对表中的字段进行定义的,为了保证数据的完整性。
primary key (主键约束 PK)保证实体的完整性,保证记录的唯一
主键约束,唯一且非空,并且每一个表中只能有一个主键,有两个字段联合作为主键,只有两个字段的值放在一起可唯一标识记录,叫做联合主键。
主键约束的定义:
第一种定义形式:
create table test(c number primary key ); 列级约束
第二种定义形式:
create table test(c number , primary key(c) ) ; 表级约束
create table test( c1 number constraints pkc1 primary key ); 约束有名字: pkc1
create table test(c number , c2 number , primary key (c ,c1) ) ; 用表级约束可以实现联合主键
foreign key (外建约束 FK)保证引用的完整性,
外键约束,外键的取值是受另外一张表中的主键或唯一值约束的,不能够取其他值,只能够引用主键或唯一键的值,被引用的表,叫做parent table(父表),引用方的表叫做child table(子表),要想创建子表,就要先创建父表,后创建子表,记录的插入也是如此,先父表后子表,删除记录,要先删除子表记录,后删除父表记录,要修改记录,如果要修改父表的记录要保证没有被子表引用。要删表时,要先删子表,后删除父表。
外键约束: (先定义父表,再定义子表)
carete table parent(c1 number primary key);
create table child(c number primary key , c2 number references parent(c1) on delete casade);列级约束定义,定义父子表纪录的级连删除
carete table parent(c1 number primary key );
create table child( c number primary key , c2 number , foreign key(c2) references parent(c1) on delete casade set null); 表级约束定义,定义父子表纪录的级连将FK置空。
not null 非空约束,这是一个列级约束
例:create table student(id number primary key,name varchar2(32) not null,address varchar2(32));
unuque key唯一约束,要求插入的记录中的值是为一的。是会忽略空值的。
例:create table student(id number,name varchar2(32),address varchar2(32),primary key (id),unique (address));
check约束
检查约束,可以按照指定条件,检查记录的插入。check中不能使用尾列(rownum),不能使用函数,不能引用其他字段。
例:create table sal (a1 number , check(a1>1000));
实体关系:
数量关系:
一对多关系:
create table class(
cid number,
color: #000