欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Oracle数据库基础(还在学java吗?不如来看看oracle)

程序员文章站 2022-03-03 19:22:37
文章目录前言 oracle sql第一章 Selecting Rows(select语句,数据查询操作)第二章 Sorting & Limiting Selected Rows(排序和限制查询)第三章 Single Row Functions(单行函数)第四章 Displaying Data from Multiple Tables(多表查询)第五章 Group Function (组函数)第六章 Subqueries(子查询(嵌套查询))第七章 Specifying V...

前言 oracle sql

  1. 一个认知
    认知什么是oracle?
    oracle:商业运用第一的关系型数据库
    实质:关系型数据库
    了解oracle数据库发展历史
  2. 二个概念
    数据库:数据存储的仓库
    关系型数据库:数据库中保存的对象之间可以存在一定的关联关系,并非完全独立。主要反映到以后学习的主外键
  3. 三个名词
    sql: 结构化的查询语句,操作oracle数据库的语言
    sqlplus: oracle软件自带的可以输入sql,且将sql执行结果显示的终端
    pl/sql: 程序化的sql语句,在sql语句的基础上加入一定的逻辑操作,如if for…,使之成为一个sql块,完成一定的功能
  4. 四种对象
    table:表格,由行和列组成,列又称字段,每一行内容为表格的一条完整的数据。
    view: 视图,一张表或者多张表的部分或者完整的映射,好比表格照镜子,镜子里面的虚像就是view
    除去常见的table和view两种对象以外,oracle数据库还支持如下四种对象
    sequence:序列
    index:索引,提高数据的访问效率
    synonym:同义,方便对象的操作
    program unit:程序单元,pl/sql操作的对象
  5. 五种分类
    sql的五大分类:
    Data retrieval:数据查询
    select
    DML:数据操纵语言(行级操作语言):操作的是表格当中一条一条的数据
    insert update delete
    DDL:数据定义语言(表级操作语言):操作的内容为表格(对象)
    create alter drop truncate rename
    transaction control:事务控制
    commit rollback savepoint
    DCL:数据控制语言
    grant revoke
--delete与truncate区别:
	delete:  删除表中的一条或者多条记录,该操作需要提交事务
	truncate:清空表格,该操作不需要提交事务

第一章 Selecting Rows(select语句,数据查询操作)

--注意:select语句永远不对原始数据进行修改。
--注意:语法中出现的中括号[],表示该部分可有可无
  1. 使用select语句查询某张表的数据内容

    --语法
    	select [distinct] *{col_name1,col_name2,..}
    	from tb_name;
    --*:表示所有列,仅仅作为测试和学习使用,在企业用语中不出现,因为效率低下且可读性差
    --col_name1:列名,将需要查阅的数据字段列举出来,可以查看多列值,列名之间用,进行分割即可
    

    例子:

    --需求:查看s_dept表中的所有记录
    	select *
    	from s_dept;
    --练习:查看s_dept表中的所有记录的id和name
    	select id,name 
    	from s_dept;
    --练习:查看所有员工的id,名字(last_name)和薪资(salary)
    	select id,last_name,salary
    	from s_emp;
    
  2. select语句可以对指定的列的所有值进行算术运算

    --语法:
    	select col_name 运算符 数字
    	from tb_name;
    

    例子:

    --需求:查看每个员工的员工id,名字和年薪。
    	select id,last_name,salary*12
    	from s_emp;
    --练习:查看每个员工的员工id,名字和月薪涨100以后的年薪
    	select id,last_name,(salary+100)*12
    	from s_emp;
    
  3. 给查询的列起别名

    --语法:
    	select old_column_name [as] new_column_name
    	from tb_name;
    

    例子:

    --需求:查看员工的员工id,名字和年薪,年薪列名为annual
    	select id,last_name,salary*12 as annual
    	from s_emp;
    
  4. 使用 || 可以使得多列的值或者列和特殊的字符串合并到一个列进行显示

    --语法:
    	select col_name||'spe_char'||col_name
    	from tb_name
    --'spe_char':如果一个列的值要跟特殊的字符串连接显示,使用该语法。
    

    例子:

    --需求:查看员工的员工id,全名
    	select id,first_name||last_name
    	from s_emp;
    --练习:查看员工的员工id,全名和职位名称,全名和职位名称合并成一列显示,且格式为:姓 名,职位名称
    	select id,first_name||last_name||,||title  name 
    	from s_emp;
    
  5. 对null值得替换运算

    --nvl()函数
    --语法:
    	select nvl(col_name,change_value)
    	from tb_name;
    

    例子:

    --需求:查看所有员工的员工id,名字和提成,如果提成为空,显示成0
    	select id,last_name,nvl(commission_pct,0) commission_pct
    	from s_emp;
    
  6. 使用distinct关键词,可以将显示中重复的记录只显示一条

    --语法:
    	select distinct col_name,col_name...
    	from tb_name;
    
    --注意1:distinct关键词只能放在select关键词后面
    	如:select id,distinct title
    	    from s_emp;
    	该语句语法错!!!!!
    	
    --注意2:如果distinct关键词后面如果出现多列,表示多列联合去重,即多列的值都相同的时候才会认为是重复的记录。
    	test表:
    	id	id2
    	1	2
    	1	3
    	2	4
    	3	4
    	3	4
    	select distinct id,id2
    	from test;
    	显示结果为:
    	id	id2
    	1	2
    	1	3
    	2	4
    	3	4
    

    例子:

    --需求:查看所有员工的职位名称和部门id,同职位同部门的只显示一次
    	select distinct title,dept_id
    	from s_emp;
    
  7. sqlplus命令(选读)

    --sqlplus 登录之后,可以使用buff(缓存)来存储/执行/修改要执行的sql语句 
       这里的buff的特点:
          1.buff中只能存储一条sql语句(但是这条sql语句可能有很多行)
          2.每次放入新的sql语句,会把之前的覆盖掉
          3.每次执行sql语句,都会把这个sql语句放到buff里面
    
    	l   查看缓存中的sql语句
    	a   在[定位]的那一行后面追加新的内容
    	i   在[定位]的那一行下面插入新的一行
    	c   替换[定位]的那一行中的某些字符串 
    		c/老的字符串/新的字符串
    	del 删除[定位]的那一行内容
    	n   后面加内容可以重写这一行
    	!   后面接终端命令 !clear:清屏 windows中使用$符号 例如:$cls
    	/   执行缓存sql命令
    
    	clear buffer:清空当前缓存的命令
    		
    	save  test.sql  buff中的sql语句保存在test.sql文件中
    	get   test.sql  把test.sql中的内容在加载到buff中,但是没有运行
    	start test.sql  把test.sql中的内容在加载到buff中并且执行
    	@test.sql       把test.sql中的内容在加载到buff中并且执行
    	edit file_name  使用系统默认编辑器去编辑文件
    
    	spool file_name 将接下来的sql语句以及sql的运行结果保存到文件中
    		sql1
    		result1
    		sql2
    		result2
    		...
    	spool off  关闭spool功能
    	exit:退出
    
  8. 修改cmd中表格显示(选读)

    select id,last_name,first_name, salary, dept_id
    from s_emp
    Where rownum <=10;
    --cmd显示结果不好看,通过column使我们的显示界面好看。
    	COLUMN last_name FORMAT a15;
    --可以简写为:
    	col last_name for a15;
    --Column 没有改变数据表里数据,它只是改变显示。Column不是SQL命令,而是sqlplus命令。
    
    --除了刚才这个作用之外,我们下面来看看它还有什么作用。
    	COLUMN last_name HEADING 'Employee|Name' FORMAT A15
    	. 给last_name取别名为Employee|Name , 竖杠代表换行。
    	. A15表示十五个字节长,一短横杠就是一个字节长
    
    	COLUMN salary JUSTIFY LEFT FORMAT $99,999.00
    	. salary JUSTIFY LEFT : 仅仅改变列名显示为左齐
    	. FORMAT $99,999.00: 控制显示格式为前面加 $ 符, “,”为分隔符, 09代表数字(通配符)0表示替换对齐数值,位数不足会补足,可以混合使用。
    
    	COLUMN start_date FORMAT A8 NULL 'Not hired'
    	. 如果start_date值为空的话,显示为’Not hired’; 
    	. Format后不能直接跟null, 要先a8或a10;
    	. NULL 'Not hired'和nvl类似
    
    	column 显示所有对列格式的设置情况
    	column last_name 显示对last_name列显示设置的情况
    	column last_name clear 删除对last_name列格式设置的情况
    	Clear column 清除所有column的格式设置
    	
    	Column columName
    	可以显示该列的格式设置,这里的列并不特定于某个表.
    
    	注意:
    	1234   column 99.99  -- > ###### //出错的时候不能显示,只是显示####
    

第二章 Sorting & Limiting Selected Rows(排序和限制查询)

  1. 排序:所谓排序,就是根据某个字段的值按照升序或者降序的情况将记录查询出来

    --语法
    	select col_name,...
    	from tb_name
    	order by col_name [asc|desc],...
    --注意:
    1.排序使用order by字句,该子句只对查询记录显示调整,并不改变查询结果,所以执行权最低,即最后执行。
    2.排序关键词:
    	asc:升序(默认,默认的意思是不加关键词的时候默认为生序排序)
    	desc:降序
    3.如果有多个列排序,后面的列排序的前提是前面的列排好序以后有重复(相同)的值。
    
  2. 限制查询,即指定查询条件进行查询

    --语法:
    	select col_name,...
    	from tb_name
    	where col_name 比较操作表达式
    	逻辑操作符
    	      col_name 比较操作表达式
    --注意:
    	1.限制查询条件,使用where子句
    	2.条件可以多个,使用逻辑操作符和()进行条件的逻辑整合
    	3.where子句的优先级别最高
    	4.比较操作表达式由操作符和值组成
    		常见的操作:
    		1》逻辑比较操作符
    		=  >  <  >=  <=
    		2》不等于:三个都表示不等于的意思(经常用的是!=)
    		!=   <>   ^=
    		3sql比较操作符SQL comparison operators
    			BETWEEN ... AND...
    			IN(list)
    			LIKE
    			IS NULL
    			(like:模糊查询,即值不是精确的值的时候使用
    			通配符,即可以代替任何内容的符号
    			% :通配0到多个字符
    			_ : 当且仅当通配一个字符
    			转义字符:
    			默认为\,可以指定 指定的时候用escape 符号指明即可,转义字符只能转义后面的一个字符)
    		4》逻辑操作符
    			当条件有多个的时候使用
    			and:且逻辑
    			or: 或逻辑
    			注意:and优先级比or优先级要高
    			not:非逻辑
    		  	NOT BETWEEN AND
                NOT IN
    			NOT LIKE
    			IS NOT NULL
    

    例子

    (逻辑比较操作符)
    --需求:查看员工工资小于1000的员工id和名字
    	select id,last_name,salary
    	from s_emp
    	where salary < 1000;
    
    (BETWEEN ... AND...)
    --需求:查看员工工资在700 到 1500之间的员工id,和名字
    	select id,last_name,salary
    	from s_emp
    	where salary between 700 and 1500;
    
    (BETWEEN ... AND...)
    --也可以在日期列上使用between and操作,但是要看当前session会话的语言环境来决定使用中文格式的日期还是英文格式的日期
    	alter session set nls_language='simplified chinese';
    	如果是中文的语言环境:
    --需求:查询在90年3月8号到91年2月9号之间入职的员工信息
    	select id,last_name,start_date
    	from s_emp
    	where start_date between '08-3月-90' and '09-2月-91';
    
    	alter session set nls_language=english;
    	如果是英文的语言环境:
    --需求:查询在90年3月8号到91年2月9号之间入职的员工信息
    	select id,last_name,start_date
    	from s_emp
    	where start_date between '08-MAR-90' and '09-FEB-91';
    
    (IN(list))
    --需求:查看是在'08-3月-90'或者'09-2月-91'入职的员工信息
         select last_name,start_date
    	 from s_emp
    	 where start_date in('08-MAR-90','09-FEB-91');
    
    (LIKE)
    --需求:查看员工名字长度不小于5,且第四个字母为n的员工id和工资
    	select id,salary,last_name
    	from s_emp
    	where last_name like '___n%' and length(last_name) >=5;
    
    --需求:查看员工名字中包换一个_的员工id和工资
    	select id,last_name,salary
    	from s_emp
    	where last_name like '%\_%' escape '\';
    
    (IS NULL)
    --需求:查看员工提成为空的员工的id和名字
    	select id,last_name,commission_pct
    	from s_emp
    	where commission_pct is null;
    
    (逻辑操作符)
    --需求:查看员工部门id为41且职位名称为Stock Clerk(存库管理员)的员工id和名字
    	select id,last_name,dept_id,title
    	from s_emp
    	where dept_id = 41
    	and
    	title = 'Stock Clerk';
    

第三章 Single Row Functions(单行函数)

函数分为:
1).单值函数
a.字符函数
b.数字函数
c.日期函数
d.转换函数
2).分组函数(后面的章节再做学习)

--哑表dual
	dual是一个虚拟表,用来构成select的语法规则,oracle保证dual里面永远只有一条记录。
	例如:
	显示1+1的结果,可以看出,dual很多时候是为了构成select的标准语法
	select 1+1 from dual;
  1. 字符函数

    LOWER		Converts to lowercase	(把字符转为小写)
    UPPER		Converts to uppercase	(把字符转换为大写)
    INITCAP		Converts to initial capitalization	(把字符串首字母转换为大写)
    CONCAT		Concatenates values	(把俩个字符串连接在一起(类似之前的||的作用))
    SUBSTR		Returns substring	(截取字符串)
    LENGTH		Returns number of characters	(获得字符串长度)
    NVL			Converts a null value	(替换列中为null的值)
    

    例子

    (lower)
    --例如:把'HELLO'转换为小写
    	select lower('HELLO')
    	from dual;		  
    --例如:把s_emp表中的last_name列的值转换为小写
    	select lower(last_name)
    	from s_emp;
    
    (upper)
    --例如:把'world'转换为大写
    	select upper('world')
    	from dual;
    --例如:把s_emp表中的last_name列的值转换为大写
    	select upper(last_name)
    	from s_emp;
    --例如:查询s_emp表中名字为Ngao的人信息
    --这样是查不到:
    	select last_name,salary,dept_id
    	from s_emp
    	where last_name='NGAO';
    --这样就可以查询到了:
    	select last_name,salary,dept_id
    	from s_emp
    	where upper(last_name)='NGAO';
    
    (initcap)
    --例如:把'hELLO'转换为首字母大写,其余字母小写
    	select initcap('hELLO')
    	from dual;
    
    (concat)
    --例如:把'hello'和'world'俩个字符串连接到一起,并且起个别名为msg
    	select concat('hello','world') msg
    	from dual;		  
    --例如:把first_name和last_name俩个列的值连接到一起
    	select concat(first_name,last_name) as name
    	from s_emp;
    
    (substr)
    --例如:截取'hello'字符串,从第2个字符开始(包含第二个字符),截取后面连续的3个字符
    	select substr('hello',2,3)
    	from dual;
    
    (length)
    --例如:获得'world'字符串的长度
    	select length('world')
    	from dual;
    
    (nvl)
    --在前面的章节已经使用过了
    	select last_name,nvl(commission_pct,0)
    	from s_emp;
    
  2. 数字函数

    ROUND		Rounds value to specified decimal(四舍五入)
    TRUNC		Truncates value to specified decimal(截取到某一位 )
    MOD			Returns remainder of division(取余)
    

    例子

    round 四舍五入
    round(arg1,arg2)
    第一个参数表示要进行四舍五入操作的数字
    第二个参数表示保留到哪一位
    --例如:
    --保留到小数点后面2位
    	select round(45.923,2)
    	from dual;
    --保留到个位 (个十百千万...)
    	select round(45.923,0)
    	from dual;
    --保留到十位 (个十百千万...)
    	select round(45.923,-1)
    	from dual;
    
    trunc 截取到某一位 
    trunc(arg1,arg2)
    和round的用法一样,但是trunc只舍去不进位
    --例如:
    --截取到小数点后面2位
    	select trunc(45.929,2)
    	from dual;
    --截取到个位 (个十百千万...)
    	select trunc(45.923,0)
    	from dual;
    --截取到十位 (个十百千万...)
    	select trunc(45.923,-1)
    	from dual;		
    
    mod 取余
    mod(arg1,arg2)	
    第一个参数表示要进行取余操作的数字
    第二个参数表示参数1和谁取余
    --例如:
    --把10和3进行取余 (10除以3然后获取余数)
    	select mod(10,3)
    	from dual;
    
  3. 日期函数

    MONTHS_BETWEEN	Number of months between two dates(俩个日期之间相差多少个月(单位是月))
    ADD_MONTHS		Add calendar months to date(返回一个日期数据:表示一个时间点,往后推x月的日期)
    NEXT_DAY		Next day of the date specified(返回一个日期数据:表示一个时间点后的下一个星期几在哪一天)
    LAST_DAY	    Last day of the month(返回一个日期数据:表示一个日期所在月份的最后一天)
    ROUND	        Round to date at midnight(对日期进四舍五入,返回操作后的日期数据)
    TRUNC	        Remove time portion  from date(对日期进行截取 和round类似,但是只舍弃不进位)
    

    例子

    sysdate关键字
    	表示系统的当前时间	
    --例如:
    --显示时间:当前时间
    	select sysdate from dual;
    注意:sysdate进行加减操作的时候,单位是天
    --例如:
    --显示时间:明天的这个时候
    	select sysdate+1 from dual;
    --例如:
    --显示时间:昨天的这个时候
    	select sysdate-1 from dual;
    --例如:
    --显示时间:1小时之后的这个日期
    	select sysdate+1/24 from dual;
    
    months_between 俩个日期之间相差多少个月(单位是月)
    --例如:
    --30天之后和现在相差多少个月
    	select months_between(sysdate+30,sysdate)
    	from dual;
    
    add_months  返回一个日期数据:表示一个时间点,往后推x月的日期
    --例如:
    --'01-2月-2020'往后推2个月
    	select add_months('01-9月-2020',2)
    	from dual;	
    --例如:
    --当前时间往后推4个月
    	select add_months(sysdate,4)
    	from dual;
    --注意:这个数字也可以是负数,表示往前推x月
    
    next_day 返回一个日期数据:表示一个时间点后的下一个星期几在哪一天
    --例如:
    --离当前时间最近的下一个星期5是哪一个天
    	select next_day(sysdate,'星期五')
    	from dual;
    --注意:
    --如果要使用'FRIDAY',那么需要把当前会话的语言环境修改为英文
    
    last_day 返回一个日期数据:表示一个日期所在月份的最后一天
    --例如:
    --当前日期所在月份的最后一天(月底)
    	select last_day(sysdate)
    	from dual;
    
    round  对日期进四舍五入,返回操作后的日期数据
    --例如:
    --把当前日期四舍五入到月
    	select round(sysdate,'MONTH')
    	from dual;
    --测试:15号16号分别是舍弃还是进位
    --把当前日期四舍五入到年
    	select round(sysdate,'YEAR')
    	from dual;
    
    trunc  对日期进行截取 和round类似,但是只舍弃不进位
    
  4. 类型转换函数

    TO_CHAR		converts a number or date string to a character string.
    TO_NUMBER	converts a character string containing digits to a number.
    TO_DATE		converts a character string of a date to a date value. 
    
    		  日期格式:
    		  yyyy:四位数的年份
    		  rrrr:四位数的年份
    		  yy:两位数的年份
    		  rr:两位数的年份
    		  mm:两位数的月份(数字)
    		  D:一周的星期几
    		  DD:一月的第几天
    		  DDD :一年的第几天
    		  YEAR:英文的年份
    		  MONTH:英文全称的月份
    		  mon:英文简写的月份
    		  ddsp:英文的第几天(一个月的)
    		  ddspth:英文序列数的第几天(一个月的)
    		  DAY:全英文的星期
    		  DY:简写的英文星期
    		  hh:小时
    		  mi:分钟
    		  ss:秒
    

    例子

    to_char 把日期转换为字符
    --例如:
    --把当前日期按照指定格式转换为字符串
    	select to_char(sysdate,'yyyy')
    	from dual;
    --例如:
    --测试常见的一些日期数据转换为字符串的格式
    	select to_char(sysdate,'yyyy MM D DD DDD YEAR MONTH ddsp ddspth DAY DY') 
    	from dual;
    
    	select to_char(sysdate,'dd-mm-yy')
    	from dual;
    
    	select to_char(sysdate,'yy-mm-dd')
    	from dual;
    
    	select to_char(sysdate,'dd-mm-yy HH24:MI:SS AM')
    	from dual;
    
    to_char 把数字转换为字符
    --例如:
    	select to_char(salary,'$999,999.00') 
    	from s_emp;
    --fm表示去除结果显示中的开始的空格
    	select to_char(salary,'fm$999,999.00') 
    	from s_emp;
    --L表示系统本地的货币符号
    	select to_char(salary,'fmL999,999.00') 
    	from s_emp;
    
    to_number 把字符转换为数字
    --例如:
    	select to_number('1000') 
    	from dual;
    --这个写法是错的 abc不能转换为数字
    	select to_number('abc')
    	from dual;
    
    to_date 把字符转换为日期
    --例如:
    	select to_date('10-9-2020','dd-mm-yyyy')
    	from dual;
    	
    	select to_date('25-5月-95','dd-month-yy')
    	from dual;
    	
    	select to_date('95/5月/25','yy/month/dd')
    	from dual;
    --session语言环境设置为英文下面可以运行
    	select to_date('25-MAY-95','dd-MONTH-yy')
    	from dual;
    
    oracle数据库中表示一个日期数据的几种方式
    	  1.使用sysdate
    	  2.使用oracle默认的日期格式 例如:'25-MAY-95'
    	  3.使用日期函数ADD_MONTHS/NEXT_DAY/LAST_DAY/ROUND/TRUNC
    	  4.使用转换函数to_date
    
    函数之间的嵌套
    	  格式:F3(F2(F1(arg0,arg1),arg2),arg3)
    	  例如:
    	  先把'hello''world'连接起来,再转换为字母大写然后再从第4个字符开始,连着截取4个字符
    	  select substr(upper(concat('hello','world')),4,4)
    	  from dual;
    

第四章 Displaying Data from Multiple Tables(多表查询)

--多表查询,又称表联合查询,即一条sql语句涉及到的表有多张,数据通过特定的连接进行联合显示
--笛卡尔积
在数学中,两个集合X和Y的笛卡尓积(Cartesian product),又称直积,表示为X × Y.
假设集合A={a, b},集合B={0, 1, 2},则两个集合的笛卡尔积为{(a, 0), (a, 1), (a, 2), (b, 0), (b, 1), (b, 2)}。
--在数据库中,如果直接查询俩张表,那么其查询结果就会产生笛卡尔积
--例如:
   select *
   from s_emp,s_dept;
  1. 连接查询
    为了在多表查询中避免笛卡尔积的产生,我们可以使用连接查询来解决这个问题.
    连接查询分为:
    1).等值连接
    2).不等值连接
    3).外连接
    a.左外连接
    b.右外连接
    c.全连接
    4).自连接
    例子:

    (等值连接)
    --利用一张表中某列的值和另一张表中某列的值相等的关系,把俩张表连接起来。
    --例如:查询员工的名字、部门编号、部门名字
    	select last_name,dept_id,name
    	from s_emp,s_dept
    	where s_emp.dept_id=s_dept.id;
    --为了表述的更加清楚,可以给每张表起别名
    	select se.last_name,se.dept_id,sd.id,sd.name 
    	from s_emp se,s_dept sd
    	where se.dept_id=sd.id;
    
    (不等值连接)
    假设数据库中还有一张工资等级表:salgrade
    工资等级表salgrade:
    gradeName列表示等级名称
    losal	 列表示这个级别的最低工资数
    hisal    列表示这个级别的最高工资数
    
    表中的数据类似于下面内容:
    id  salgrade	losal hisal
    1  初级程序员   2000  4000
    2  中级程序员   4000  6000
    		
    --例如:
    --查询出员工的名字、职位、工资、工资等级名称
    	SELECT  e.last_name, e.title, e.salray, s.gradeName
    	FROM    s_emp e, salgrade s
    	WHERE   e.salray BETWEEN s.losal AND s.hisal
    
    (外连接)
    --外连接分为:左外连接,右外连接,全连接
    先分别在俩s_emp和s_dept表中插入新的数据
    特点:新员工tom不在任何部门,新增部门st下面没有任何员工
    	insert into s_emp(id,last_name) values(26,'tom');
    	insert into s_dept(id,name) values(60,'st');
    	commit;
    	
    --这个时候再使用等值连接的话,查询出来的数据就会少,因为新增的员工tom和部门表中的数据连接不上,
    --当然新增的部门st也和员工表中的数据连接不上.那么这俩条数据都是在等值连接中查询不出来.
    
    (左外连接)
    --例如:
    --查询所有员工 以及对应的部门的名字,没有部门的员工也要显示出来
    	select last_name,dept_id,name 
    	from s_emp,s_dept
    	where s_emp.dept_id=s_dept.id(+);		
    		或者(俩者是等价的)
    	select last_name,dept_id,name 
    	from s_emp left outer join s_dept
    	on s_emp.dept_id=s_dept.id;
    --注意:outer可以省去不写	
    (右外连接)
    --例如:
    --查询所有员工 以及对应的部门的名字,没有任何员工的部门也要显示出来
    	select last_name,dept_id,name 
    	from s_emp,s_dept
    	where s_emp.dept_id(+)=s_dept.id;
    		或者(俩者是等价的)
    	select last_name,dept_id,name 
    	from s_emp right outer join s_dept
    	on s_emp.dept_id=s_dept.id;
    --注意:outer可以省去不写
    (全连接)
    --例如:
    --查询所有员工 以及对应的部门的名字,没有任何员工的部门也要显示出来,没有部门的员工也要显示出来
    	select last_name,dept_id,name 
    	from s_emp full outer join s_dept 
    	on s_emp.dept_id=s_dept.id;
    --注意:outer可以省去不写
    
    (自连接)一张表,自己和自己连接,一张表分两个角度看
    --例如:
    --查询每个员工的名字以及员工对应的管理者的名字
    	select s1.last_name,s2.last_name manager_name
    	from s_emp s1,s_emp s2
    	where s1.manager_id = s2.id;
    
  2. 对查询结果集的操作

    --如果有俩条sql语句,每一条sql都可以查询出一个结果,这个被称之为结果集。那么我们可以使用下面的关键字对俩个结果集进行操作
    	union		取俩个结果集的并集 
    	union all	把俩个结果集合在一起显示出来	
    	minus    	第一个结果集除去第二个结果集和它相同的部分
    	intersect	求俩个结果集的交集
    --注意:前提条件 俩个结果集中查询的列要完全一致
    
  3. 伪列rownum

    oracle中的伪列 rownum
    	--伪列rownum,就像表中的列一样,但是在表中并不存储。伪列只能查询,不能进行增删改操作。
    	--它会根据返回的结果为每一条数据生成一个序列化的数字.rownum是oracle才有的伪列
    	rownum 所能作的操作:
    --rownum 只能等于1  如果让其等于其他数 则查不到数据
    	例如:
    	select last_name
    	from s_emp
    	where rownum=1
    --rownum 大于0 如果让其大于其他数 则查不到数据
    	例如:
    	select last_name
    	from s_emp
    	where rownum>0
    --rownum 可以小于任何数
    	例如:
    	select last_name
    	from s_emp
    	where rownum<7
    

    拓展(伪列配合结果集的操作)

    拓展(伪列配合结果集的操作)
    --例如查询部门表中第3条到第5条数据?
    	select *
    	from s_emp
    	where rownum <= 5
    	minus
    	select *
    	from s_emp
    	where rownum < 3;
    --例如每页展示5条数据,查询员工表(s_emp)中第三页数据
    	select *
    	from s_emp
    	where rownum <= 15
    	minus
    	select *
    	from s_emp
    	where rownum < 11;
    

第五章 Group Function (组函数)

sql语句的各部分构成
	select   ....
	from	 ....
	where	 ....
	group by ...
	having	 ...
	order by ....
--注意:除了select和from之外其他的都不是必须的。
--假如select..from..后面的语句都出现了,那么他们的执行顺序为:
--where-->group by分组-->执行组函数-->having筛选->order by

组函数(group by/having):
avg 求平均值
count 计算有多少条数据
max 最大值
min 最小值
sum 求和
stddev 标准差
variance 方差

--组函数出现的位置: 
	1.select后面 
	2.having后面 
	3.order by后面
	4.where后面一定【不能】出现组函数
	注意:如果select/having语句后面出现了组函数,那么select/having后面没有被组函数修饰的列,就必须出现在group by 后面
--where和having对比:
	1.wherehaving都是做条件筛选的
	2.where执行的时间比having要早
	3.where后面不能出现组函数
	4.having后面可以出现组函数
	5.where语句要紧跟from后面
	6.having语句要紧跟group by后面
--group by和having的关系:
	1.group by可以单独存在,后面可以不出现having语句
	2.having不能单独存在,有需要的话,必须出现在group by后面
--order by语句
	1.如果sql语句中需要排序,那么就一定要写在sql语句的最后面
	2.order by后也可以出现组函数

例子:

使用组函数:不结合group分组使用
(注:如果不使用group分组的话,那么默认当前查询到的所有数据是一组)
--例如:查询s_emp表中所有员工的平均工资
	select avg(salary)
	from s_emp;
--例如:查询s_emp表*有多少条数据
	select count(*)
	from s_emp;
使用组函数:结合group分组使用
--例如:查询s_emp表中每个部门的平均工资
	select dept_id,avg(salary)
	from s_emp
	group by dept_id;
--例如:查询s_emp表中每个部门员工的工资总和
	select dept_id,sum(salary)
	from s_emp
	group by dept_id;
使用组函数:结合group分组以及having筛选使用
--例如:查询s_emp表中部门的平均工资大于等于1400的部门
	select dept_id,avg(salary)
	from s_emp
	group by dept_id
	having avg(salary)>=1400;
使用组函数:其他实例
--例如:查询s_emp表中部门的平均工资大于等于1400的部门,并且显示出这些部门的名字,同时按照部门编号进行排序
	select dept_id,avg(salary),s_dept.name
	from s_emp,s_dept
	where s_emp.dept_id=s_dept.id
	group by dept_id,s_dept.name
	having avg(salary)>=1400
	order by dept_id;

第六章 Subqueries(子查询(嵌套查询))

子查询,即一个select语句中嵌套了另外的一个或者多个select语句
(select语句) 可以放在from,where,group by,having,order by任意位置,进行嵌套
(语法简单,逻辑复杂)

例子:

--例如:查询工资比Simth工资高的员工信息
	--第一步:查询Smith的工资数
		select salary
		from s_emp
		where last_name='Smith';	
		结果:
			SALARY
		----------
			   940
	--第二步:查询工资比940高的员工信息
		select last_name,salary
		from s_emp
		where salary>940;
	--第三步:把第二步中的数字940替换成第一步中的sql语句即可(注意格式)
		select last_name,salary
		from s_emp
		where salary>(
			select salary
			from s_emp
			where last_name='Smith'
		);
--查询工资比 Ngao所在部门平均工资 要高的员工信息,同时这个员工所在部门的平均工资 也要 比Ngao所在部门的平均工资要高,显示当前部门的平均工资以及部门的名字和所在地区
    select s1.id,s1.last_name,s1.salary,s1.dept_id,s4.name,s5.name
    from s_emp s1,
         (select dept_id ,avg(salary) mysal
         from s_emp
         group by dept_id)s2,
               (select s1.dept_id,avg(s1.salary) mysal
               from s_emp s1,
               (select last_name,dept_id
               from s_emp 
               where last_name='Ngao') s2
               where s1.dept_id in (s2.dept_id)
               group by s1.dept_id) s3,
                     s_dept s4,
                            s_region s5
    where s1.dept_id=s2.dept_id
    and s2.mysal>s3.mysal
    and s1.salary>s3.mysal
    and s1.dept_id=s4.id
    and s4.region_id=s5.id;

第七章 Specifying Variables at Runtime(运行时参数)

sql语句中的值,我们可以使用一个参数来代替,然后每次运行的时候都可以重新输入这个值。

--例如:
select last_name,salary,dept_id
from s_emp
where id=&id;
--例如:
select last_name,salary,dept_id
from s_emp
where last_name=&name;
--注意:&变量名 表示使用这个oracle定义的变量,如果这个变量之前没有定义过,那么这个时候会让你重写输入这个变量的值.
如果之前有定义过,那么就是要之前定义过的值

define undefine accept prompt命令
例如:
命令def可以定义一个变量
定义变量: def A=s_emp
查看定义的变量: def
取消定义的变量: undef A

然后变量A之前定义过,那么这里会之前替换为之前定义的值
select id,last_name,salary
from &A;

accept命令也可以定义一个变量,而且变量的值需要用户再次输入
例如:
accept A
回车之前需要用户再次输入变量A的值
之后可以使用def命令来查看刚刚定义的A变量

prompt可以在用户输入的时候显示一个提示信息:
例如:
accept name prompt '请输入name变量的值:'

hide可以隐藏用户的输入内容不被看见
例如:
accept name prompt '请输入name变量的值:'hide

注意:这些定义的都是临时变量,sqlplus退出后重新登录进来就没有了

第八章 Overview of Data Modeling and Database Design(数据建模和数据库设计)

  1. 软件开发的步骤可大致分为:
    1).需求分析
    2).系统设计
    3).编码实现
    4).系统测试
    5).运行维护

    系统设计中一个重要的环节就是数据库设计

    数据库设计的时候需要先进行数据建模(实体关系图 E-R图)

    数据建模的依据就是前期所做的需求分析

  2. 实体-关系图
    1).实体-关系图(Entity Relationship Diagram),也称为E-R图,提供了表示实体、属性和关系的方法,用来描述现实世界的概念模型。

    2).构成E-R图的基本要素是实体、属性和关系

    ​ a.实体(Entity):实体用来表示具有相同特征和性质的事物(类似于java的类),实体由实体名和实体属性来表示。

    ​ b.属性(Attribute):实体所具有的某一特性,一个实体可以有若干个属性

    ​ c.关系(Relationship):实体彼此之间相互连接的方式称为关系。一般可分为以下 3 种类型:
    ​ 一对一关系 (1 ∶ 1)
    ​ 一对多关系 (1 ∶ N)
    ​ 多对多关系 (M ∶ N)

  3. may-be 和 must-be
    在实体与实体之间的关系中,都会存在着may-be和must-be这俩种情况,例如:
    系统中有顾客和订单俩个实体(1:N关系),一个顾客对应多个订单,一个订单对应一个顾客,而且一个顾客可以(may be)没有订单和他对应,一个订单一定(must be)会有顾客和它对应.

  4. ER图中符号的表示
    1) # : 唯一, 以后可能表示为主键
    2) * : 非空
    3) o : 可有可无
    4) 虚线: may be 顾客这边虚线,顾客可能没有订单
    5) 实线: must be 订单这边实线,订单一定是属于某个客户。
    6) 竖杠(|): 代表要强制在(|)一方建立一个联合主键,将对方ID拿过来做联合主键
    7) 伞状图标代表多的一方,不是伞状图标则代表一的一方

  5. 数据库设计
    数据建模完成之后,可以把ER图转换成数据中的表
    1).实体的名字转换为表的名字
    2).实体的属性转换为表中的列
    3).具有唯一特点的属性设置为表中的主键
    4).根据实体之间的关系设置为表中某列为外键列(主外键关联)
    注意:第四步主要是:实体关系—>表关系
    设计关系数据库时,遵从不同的规范要求,才能设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式数据库冗余越小。

    ​ 目前关系数据库有六种范式:
    ​ 第一范式(1NF)
    ​ 第二范式(2NF)
    ​ 第三范式(3NF)
    ​ 巴斯-科德范式(BCNF)
    ​ 第四范式(4NF)
    ​ 第五范式(5NF,又称完美范式)

    ​ 注:满足最低要求的范式是第一范式(1NF)。在第一范式的基础上进一步满足更多规范要求的称为第二范式(2NF),其余范式以次类推。一般说来,数据库只需满足第三范式(3NF)就行了

    --第一范式:
    	    一个表中,每个列里面的值是不能再分割的.
    	    例如:我们设计的表中有一个列是:爱好
    	    这个列的值可能会是这样:足球篮球乒乓球
    	    但是这值是可以再分割的:足球、篮球、乒乓球
    	    所以这种设计是不满足第一范式
    --第二范式:
    		第二范式是在满足第一范式的基础上
    	    表中的非主键列都必须依赖于主键列
    	    例如:
    	    订单表: 订单编号 是主键
    	    订单编号  订单名称   订单日期  订单中产品的生产地
    	    这几个非主键列中,产品生产地是不依赖于订单编号的,所以这种设计是不满足第二范式
    --第三范式:
    		第三范式是在满足第二范式的基础上
    		表中的非主键列都必须直接依赖于主键列,而不能间接的依赖.
    		(不能产生依赖传递)
    	    例如:
    	    订单表:   订单编号 是主键
    	    订单编号  订单名称  顾客编号  顾客姓名
    	    顾客编号依赖于订单编号,顾客姓名依赖于顾客编号,从而顾客姓名间接的依赖于订单编号,那么这里产生了依赖传递,所以这个设计是不满足第三范式的
    
  6. 了解主键和外键
    主键:
    1).能做主键的列必要满足非空唯一的特点
    2).只要满足非空唯一的任何列都可以做主键
    3).可以让表中一个有意义的列做主键,比如说学号,它既表示学生学号又作为表中的主键,因为这个列满足非空唯一的条件
    4).也可以找一个没有意义的列做主键,就是用来唯一标识一行记录的
    5).我们可以让多个列联合在一起做表中的主键,那么它就是联合主键,要求这几个列的值联合在一起是非空唯一的

    外键:
    1).表中的某一个列声明为外键列,一般这个外键列的值都会引用于另外一张表的主键列的值(有唯一约束的列就可以,不一定非要引用主键列)
    2).另外一张表的主键列中出现过的值都可以在外键列中使用,没有出现过的值,都不能使用
    3).外键列值也可以为空的,提前是这个外键列在表中不做主键,因为我们也可以把表中的外键列当做主键来使用(只有满足非空唯一的要求就可以)
    4).如果把B表中的联合主键的值引用到A表中做外键,因为是俩个列在B表中做联合主键,那么A表引用过来的时候也要把俩个列的值都引用过来,那么它们在A表中就会作为一个联合外键出现

第九章 Creating Tables(建表)

1.关键字
2.表名
3.列名
4.数据类型
5.约束
6.固定格式
7.特殊建表

  1. 关键字(create)

  2. 表名
    1).必须是字母开头
    2).必须是1-30个字符之间的长度
    3).表名中只能出现A–Z, a–z, 0–9, _, $, #
    4).不能和数据库中已有对象的名字重复
    5).不能是数据库中的关键字

  3. 列名
    自定义name

  4. 常用数据类型
    1).char
    2).varchar
    3).varchar2
    4).number
    5).date
    6).其他类型 BLOB CLOB
    BLOB和CLOB都是大字段类型,BLOB是按二进制来存储的,而CLOB是可以直接存储文字的

    char varchar varchar2的区别及特点
    		1CHAR的长度是固定的,而VARCHAR2的长度是可以变化的
    		2CHAR的效率比VARCHAR2的效率稍高。 
    		3VARCHAR是数据库标准的字符类型
    		4. VARCHAR2是Oracle自己开发了一个数据类型VARCHAR2
    		5. VARCHAR2将数据库中varchar列可以存储空字符串的特性改为存储NULL值。
    		6.Oracle建议使用VARCHAR2而不是VARCHAR
    
  5. 约束
    其中,约束分为列级约束(因为是跟在列的声明后面写的)和表级约束(因为是在全部列声明完之后写的),列级约束和表级约束都是对列中的值进行约束的,例如:列的值不能为空,列的值必须是唯一的等等。
    注:列级约束也称为行级约束
    同时,列级约束和表级约束都是可选的,也就是都可以写也可以不写。

    --例如:
    	create table 表名(
    		列名1 数据类型,
    		列名2 数据类型,
    		列名3 数据类型,
    		列名4 数据类型
    	);
    

    列级约束
    列的约束就是对这个列中的值的要求
    1.主键约束 PRIMARY KEY primary key
    2.外键约束 FOREIGN KEY foreign key
    3.唯一约束 UNIQUE unique
    4.非空约束 NOT NULL not null
    5.check约束 CHECK check

    表级约束
    注:非空约束(not null)不能声明成表级约束

    表级约束和列级约束对比
    1.表级约束和列级约束所写的位置不一样
    2.not null约束不能用表级约束来声明
    3.表级约束和列级约束声明语法稍有所不同
    4.如果要声明的约束为联合主键、联合外键、联合唯一的时候,就一定要用表级约束

    constraint关键字
    1.constraint是约束的意思
    2.建表的时候可以给约束起一个名字,这个名字起的规律一般会是:表名_列名_约束类型
    3.如果没有给约束起名字,那么系统也会给这个约束起一个默认的名字,这不过这个默认的名字对我们来说并不友好(我们看不懂)
    4.将来我们可以根据我们之前给约束起好的名字而找到这个约束,然后进行修改

    例子:

    --例如1:
    --列级约束 起约束名字
    		create table student(
    			id number constraint student_id_pk primary key,
    			name varchar2(100) constraint student_name_nn not null,
    			email varchar2(100) constraint student_email_un unique,
    			gender char(1) constraint student_gender_ck check(gender in('f','m')),
    			age number,
    			birthday date
    		);	
    		drop table student;
    --例如2:
    --表级约束 起约束名字
    		create table t_customer(
    			id number,
    			name varchar2(20) not null,
    			age number,
    			email varchar2(100),
    			gender char,
    			constraint cus_id_pk primary key(id),
    			constraint cus_email_un unique(email),
    			constraint cus_gender_ck check(gender in('f','m'))
    		);
    		create table t_order(
    			id number,
    			price number not null,
    			customer_id number,
    			constraint order_cid_fk foreign key(customer_id) references t_customer(id)
    		);
    		drop table t_order;
    		drop table t_customer;
    
  6. 固定格式

    --建表的格式
    	create table 表名(
    	列名1 数据类型 列级约束,
    	列名2 数据类型 列级约束,
    	列名3 数据类型 列级约束,
    	列名4 数据类型 列级约束
    	);
    --------------------------
    	create table 表名(
    	列名1 数据类型 列级约束,
    	列名2 数据类型 列级约束,
    	列名3 数据类型 列级约束,
    	列名4 数据类型 列级约束,
    	表级约束1,
    	表级约束2
    	);	
    
  7. 特殊建表

    --例如1:
    --s_dept的表结构和表中的数据全部复制过来
    		create table test1
    		as
    		select * from s_dept;
    		
    --例如2:
    --只拿来s_dept的表结构,没有数据
    		create table test2
    		as
    		select * from s_dept
    		where 1=2;
    		
    --例如3:
    --只复制表中某几个列以及数据
    		create table test3
    		as
    		select id,last_name,salary from s_emp;
    

第十章 Oracle Data Dictionary(数据字典)

作用:帮助用户了解当前数据库的一些信息或是对象的信息或是用户的信息
1.数据字典在数据库被创建时创建的。
2.数据字典中的数据被数据库服务器自动更新和维护

常见的数据字典(它们都是视图)
USER开头的视图里面存放着用户自己拥有的对象
ALL开头的视图存放着用户有权限查看的对象
DBA开头的视图存放着数据库所有的对象
V$开头的视图存放数据库运行的一些性能属性数据

--以user开头的数据字典: 包含当前用户所拥有的相关对象信息。
	//查询用户拥有的所有表的名字
	select table_name from user_tables; 
	
	//查询用户对象表,找出对象类型是TABLE类型的对象名字
	//table view sequence index synonym等都是oracle中的对象
	//注意字符串的值是区分大小写的
	select object_name
	from user_objects
	where object_type = upper('table');
	
	//查询用户对象表,找出对象类型都有哪些
	select distinct object_type
	from user_objects;
	
	//查询出s_emp表中的列及其对应的约束名字
	select constraint_name, column_name
	from user_cons_columns
	where table_name = 'S_EMP';
	
	//查询出s_emp表中的约束名字
	select	constraint_name
	from	user_constraints
	where	table_name = 'S_EMP';
--以all开头的数据字典:  包含当前用户有权限访问的所有对象的信息
	//查到当前用户有权限访问的对象
	select table_name from all_tables;  
--以dba开头的数据字典:  包含数据库所有相关对象的信息。
	//只能是有dba权限的用户查询,能查到数据库中所有对象
	select table_name from dba_tables; (sys system)
其他视图:DICTIONARY
dictionary视图中只有俩列:
TABLE_NAME表示当前表的名字
COMMENTS表示对这个表的描述

SQL> desc dictionary
 名称
 -----------------------------------------

 TABLE_NAME
 COMMENTS
select *
from dictionary
where table_name='USER_TABLES';

select *
from dictionary
where table_name='ALL_TABLES';

select table_name
from dictionary
where table_name like 'USER%';

select table_name
from dictionary
where table_name like 'ALL%';

select table_name
from dictionary
where table_name like 'V$%';

第十一章 Manipulating Data(DML)(DML语句)

主要内容:
insert
update
delete
commit
savepoint
rollback

  1. insert语句:

    --向表中插入数据:
    	--默认是向表中的每一个列中【依次】插入数据
    		insert into t_user values(1,'tom','abc','f',20,'11-8月-98');
    	--违反任意一种约束那么就插入数据失败
    	--也可以指明向表中的哪些列插入数据
    	--注意:可以任意交换下面列名的位置,只有values语句中的值也对应交换即可
    		insert into t_user(id,name,email,gender,age,birthday)
    		values(2,'tom','abc1','f',20,'11-8月-98');
    
    	--列的值可以是null的话,那么也在插入的时候不指定这个列
    	--注意:unique约束和check约束的值,都可以为null
    	--注意:主键约束和非空约束的值,都不可以为null
    		insert into t_user(id,name,email,gender) values(3,'tom','abc3','f');
    		insert into t_user(id,name,email) values(4,'tom','abc3');
    		insert into t_user(id,name) values(5,'tom');
    	--把查询的结果 插入到表中
    	--前提是查询的列的顺序和要插入表中列的顺序是一致的,这个一致指的的是数据类型是一种的
    		insert into t_user(id,name,birthday) 
    		select id,last_name,start_date 
    		from s_emp;
    
  2. update语句

    --修改表中所有数据的age值为20岁
    	update t_user set age=20;
    		
    --修改表中所有数据的age和gender的值
    	update t_user set age=25,gender='m';
    		
    --修改表中id小于10数据的age和gender的值为null
    	update t_user 
    	set 
    	age=null,gender=null 
    	where id<10;
    --修改id为18的用户的名字为zhangsan
    	update t_user set name='zhangsan' where id=18;
    
  3. delete语句:

    --删除表中id大于20的用户信息
    	delete from t_user where id>20;
    --删除名字为张三的用户信息
    	delete from t_user where name='zhangsan';
    --删除表中所有的数据
    	delete from t_user;
    

    数据库事务
    1).DML语句执行的时候,如果当前有事务,那么就使用这个事务,如果当前没有事务,这个执行的DML语句就会产生一个新的事务。
    2).只有DML语句才会产生事务,其他语句不会产生事务。
    3).commit/rollback/DDL语句都可以把当前事务给结束掉
    4).commit和DDL语句结束事务的方式是把这个事务给提交了
    5).rollback结束事务的方式是把这个事务给回滚了
    注:
    提交事务是指让这个事务里面的所有操作都生效到数据库中
    回滚事务是指让这个事务里面的所有操作都撤销

    --例如1:
    		insert ....产生事务A
    		update ... 这个操作是事务A中的操作
    		insert ..  这个操作是事务A中的操作
    		commit;    让事务A里面的三个操作生效、事务A结束
    		delete ... 产生新的事务B
    		insert ..  这个操作是事务B中的操作
    		insert ..  这个操作是事务B中的操作
    		insert ..  这个操作是事务B中的操作
    		rollback;  让事务B中的四个操作都撤销,事务B结束
    
    --例如2:
    		insert ....产生事务A
    		update ... 这个操作是事务A中的操作
    		insert ..  这个操作是事务A中的操作
    		DDL语句;   事务A会被提交,事务A结束
    		rollback;  这时候回滚已经对事务A不起作用,因为事务A以及被提交了,当前已经没有事务了
    		
    	--注:create语句 drop语句 alter语句等都属于DDL语句
    

    事务特征ACID: (四个特性很重要,一定要熟记)

    原子性:Atomicity
    		同时成功或者同时失败
    一致性:Consistency 
    		事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。
    隔离性:Isolation 
    		事务操作应该相互独立
    持久性:Durability 
    		事务所做的影响 ,在事务结束之后应该能够是持久的。
    
    --isolation  事务隔离级别
    		
    	--事务中产生的问题:
    
    		1.脏读  主要针对update操作。 一个事务A读到另一个事务B中修改过但是还没有提交的数据
    
    		2.不可重复读  主要针对update操作。 一个事务A在第一次读数据和第二次读数据之间,有另一个事务B把这个数据更改并提交了。
    					 所以就出现了事务A里面读一个数据俩次,但是读到的结果是不同的。
    
    		3.幻读  主要针对的是insert/delete操作。事务A第一次用where条件筛选出了10条数据,事务A第二次用通样的where条件筛选出的却是11条数据。
    		        因为事务B在事务A的第一次和第二次查询之间进行了插入操作,并且插入的这个数据满足事务A的where筛选条件.
    		
    	--事务隔离级别有:
    		read-uncommitted  不提交也能读
    		read-committed    提交之后才能读 解决了脏读
    		repeatable-read   解决了脏读和不可重复读
    		serializable      三个问题都解决了
    
    		--级别越高解决的问题越多但是效率越低。
    		--注意:并不是所有数据库都支持这四种事务隔离级别,比如oracle就只支持第二种和第四种这俩种,比如mysql就四种全支持.
    
    		--oracle里面默认的事务隔离级别是第二种:read-committed
    
    		oralce里面设置事务隔离级别:
    		Set Transaction Isolation Level Read Uncommitted
    		Set Transaction Isolation Level Read Committed
    		Set Transaction Isolation Level Read Repeatable
    		Set Transaction Isolation Level Serializable
    

    回滚点/保存点 savepoint

    --回滚点/保存点 savepoint
    	--例如:
    		DML语句1
    		savepoint A
    		DML语句2
    		savepoint B
    		DML语句3
    		rollback to A/B
    	--这个时候可以通过这个回滚点让事务回滚到指定的位置,如果不指定回滚点而是直接rollback,那么事务会一下子回滚完.
    	--【特别注意】:rollback到回滚点之后,这个事务并没结束,这个时候还可以接着回滚或者commit提交事务。
    

    例子

    --例如:
    	insert into t_user values(1,'tom',1000);
    	savepoint A;
    	insert into t_user(id,name) values(2,'zs');
    	savepoint B;
    	delete from t_user;
    	rollback to B;
    --然后查询看结果
    	select * from t_user;
    

第十二章 Altering Tables and Constraints(修改表和约束(alter语句))

--在表中添加一个新的列
	alter table t_user
	add birthday date;

--删除表的某列
	alter table t_user
	drop column birthday;

--给表中的列添加约束
--这个约束相当于之前的表级约束
	alter table t_user
	add constraint user_name_un
	unique(name);
	
--测试刚添加的唯一约束是否生效
	insert into t_user(id,name) values(1,'zs');
	insert into t_user(id,name) values(2,'zs');
	
--删除表中的约束
	alter table t_user
	drop constraint user_name_un;

--修改表的名字:
	rename t_user to mytest;
	rename mytest to t_user;

--修改表中某列的类型
	alter table t_user
	modify (name varchar2(500));

--让约束失效:必须知道约束的名字
	alter table t_user
	disable constraint user_id_pk cascade;
	
--测试是否设置成功
	insert into t_user(id,name) values(1,'zs1');
	insert into t_user(id,name) values(1,'zs2');

--让失效的约束再次生效
	alter table t_user
	enable constraint user_id_pk;

--截断表中的数据(删除),不需要提交,默认已经提交,并且不能回滚
	truncate table t_user;
	相当于:
	delete from t_user;
	commit;

--给表添加注释
	comment on table t_user is '很好';
--给列添加注释
	comment on column t_user.name is 'good';
--查看表中注释
	select * from user_tab_comments where table_name=upper('t_user');
--查看列中的注释
	select * from user_col_comments 
	where 
	comments is not null 
	and 
	table_name=upper('t_user');

第十三章 Creating Sequences(序列)

Sequence 序列

Sequence 序列
	--作用:帮我们生成主键列的值(特点:非空唯一)

	--创建序列:
	--一般不需要设置sequence的属性,使用默认的方式去创建就可以了.
	create sequence 序列名;

	如果需要设置属性,那么就加上下面的语句.
	[INCREMENT BY n]  每次拿出值加多少
	[START WITH n]    初始值从几开始
	[{MAXVALUE n | NOMAXVALUE}]  最大值
	[{MINVALUE n | NOMINVALUE}]  最小值
	[{CYCLE | NOCYCLE}]  到了最大值后是否循环(如果循环会从1开始)
	[{CACHE n | NOCACHE}] 每次在缓存里面放多少个值.

	--例如:创建序列并设置属性
		create sequence seq_test 
		increment by 2
		start with 45
		maxvalue 60
		cycle
		nocache;
	
		drop sequence seq_test;

	--例如:创建序列使用默认属性
		create sequence seq_test;

	
	对应序列,我们只有俩种操作:
		1.获得序列中的下一个值
			//这个值对于当前这个序列来的其他值来说,肯定是非空唯一
			select seq_test.nextval
			from dual;

		2.查询序列中当前的值是多少
			select seq_test.currval
			from dual;

	
	向t_user表插入数据,其中id值可以需要生成
		create table t_user(
			id number constraint user_id_pk primary key,
			name varchar2(100),
			salary number
		);
		drop table t_user;
	
	--创建序列
		drop sequence t_user_seq;
		create sequence t_user_seq;
	
	--插入数据 使用序列产生id值
		insert into t_user(id,name,salary) values(t_user_seq.nextval,'tom',2000);
	

	通过数据字典查询当前用户的序列
		select sequence_name
		from user_sequences;

第十四章 Creating View(视图view)

视图view
视图就是提取一张或者多张表的数据生成一个映射,操作视图可以达到操作原表的效果,方便数据的管理以及安全操作。
1).视图的作用:
1.隐藏表中的重要数据
2.代替一些比较长的sql语句
2).视图分为俩类:
简单视图:
视图所代表的sql中如果没有group by语句,没有组函数,查询的只有一张表,那么这样的视图就是简单视图.
复杂视图
视图所代表的sql中如果有group by语句,或者有组函数,或者查询的是多张表,那么这样的视图就是复杂视图.
3).简单视图和复杂视图的区别:
通过简单视图可以修改原来表中的数据,通过复杂视图是不能修改原来的数据的。

--创建视图
		create or replace view 视图名字
		as
		sql语句
--删除视图
		drop view 视图名字;
--测试表:
	create table t_user(
		id number constraint user_id_pk primary key,
		name varchar2(100),
		salary number
	);
	drop table t_user;
	
--插入数据:
	insert into t_user(id,name,salary) 
	select id,last_name,salary
	from s_emp;

--创建视图
	create or replace view v_test
	as
	select *
	from t_user
	where id > 10;

--查看视图内容
	select *
	from v_test;


--可以通过*简单视图*对原来的表进行数据的删除/更新/插入
	delete from v_test where id=16;

	update v_test set name = 'zhangsan' where id = 20;

	insert into v_test(id,name,salary) values(28,'tom1',3000);
--with read only语句 
	--特点:只能通过视图进行查询数据,不能修改
	--例如:
		create or replace view v_test
		as
		select *
		from t_user
		where id > 10
		with read only;
		
	--这个视图v_test将来只能查询,不能进行修改

--ith check option语句
	--特点:通过视图进行的修改 那么也必须可以通过这个视图能够显示出来,要不然就操作失败

--例如:
	--测试用的表及其数据
		drop table t_user;
		create table t_user(
			id number constraint user_id_pk primary key,
			name varchar2(100),
			salary number
		);

		insert into t_user values(1,'tom',1000);
		insert into t_user values(2,'tom2',2000);
		
	--创建视图:
		create or replace view v_test
		as
		select id,name,salary
		from t_user
		where id=2
		with check option;
		
	--查询视图中的数据
		select * from v_test;

	--插入报错 因为这个操作通过视图显示不出来
		insert into v_test values(3,'tom3',3000);

	--更新失败 因为这个操作通过视图显示不出来
		update v_test
		set name='lily'
		where id=1;

	--更新成功 因为这个操作通过视图可以显示出来
		update v_test
		set name='lily'
		where id=2;
--复杂视图
	--例如:
			create or replace view v_test
			as
			select avg(salary)
			from t_user
		
	--复杂视图只能用来查询,不能修改

第十五章 Creating Indexes(索引(index))

索引的概念:
1.类似书的目录结构
2.Oracle 的"索引"是一种对象,是与表关联的可选对象,能提高SQL查询语句的速度
3.索引直接指向包含所查询值的行的位置,减少磁盘I/O
4.索引和表是相互独立的物理结构
5.Oracle 自动使用并维护索引,插入、删除、更新表后,自动更新索引

--索引的创建:
	--1.自动创建
		当在表中指定了primary Key或者unique约束时会自动创建唯一值索引。
	--2.用户创建。
		用户可以创建非唯一值索引以提高在访问数据时的效率。
		语法:
			create index 索引名
			on 表名(列名);
		例如:
			create index emp_index
			on s_emp(last_name);
		删除索引:
			drop index 索引名;
		例如:
			drop index emp_index;
			
		创建成功后可以通过如下语句查看:
			 select index_name from user_indexes;
--给某列创建索引的原则:
		1.列经常作为where子句的限定条件或者作为连接条件
		2.列包含的数据量很大,并且很多非空的值。
		3.两个或者更多列频繁的组合在一起作为where的限定条件或者连接条件
		4.列总是作为搜索条件
		5.索引查出的数据量占2%~4%
		6.索引不是越多越好,不是索引越多越能加速查找。
		7.要索引的表不经常进行修改操作
	
	--注意:
		1.在表中的某一个合适的列加入上了索引,那么也只有在数据量很大的时候,才能有所体现出这个查询的效率.
		2.索引一旦建立成功,那么之后这个索引就由系统来管理,我们自己是控制不了的.


--索引的种类:
		Single column 单行索引
		Concatenated  多行索引
		Unique		  唯一索引
		NonUnique     非唯一索引
	
--索引结构分为:
		1.B-tree(默认是这种结构)
			适合大量的增、删、改(OLTP);
			不能用包含OR操作符的查询;
			适合高基数的列(唯一值多)
			典型的树状结构;
		2.位图
			做UPDATE代价非常高(oracle要根据表的每次修改来更新索引)
			非常适合OR操作符的查询;

		3.反序
		4.函数

第十六章 Controlling User Access用户权限控制

--1.创建用户
		create user user_name identified by password
	--例如:
		create user test identified by test;

--2.删除用户
		drop user test cascade;

--3.赋予权限
		grant privilege to user;
	--例如:把建表 建序列 建视图的权限赋给test
		grant create table, create sequence,create view to test;

	--把connect角色和resource角色赋给test
	--角色是一组权限的集合
		grant connect,resource to test;
		
	--注意: 只是登陆oracle数据库的话 需要的权限是create session
		
--4.修改密码
		alter user user_name identified by password;
	--例如:
		alter user test identified by zhangsan123;

--5.赋予某一个用户某种对象操作的权限
		grant operator on object to user;
	--例如:
		grant select 
		on t_user 
		to test; 

--6.回收权限
		revoke operator on object from user;
	--例如:
		revoke select 
		on t_user 
		from test;
		
--7.创建同义词synonym
	--作用:可以隐藏表原来的信息
	--分为:私有同义词 公共同义词

	--给表t_user创建一个私有同义词
		create synonym my_test
		for t_user;
		
	--给用户briup授权可以查询my_test
		grant select 
		on my_test 
		to test; 

	--收回用户test查询my_test的权限
		revoke select 
		on my_test 
		from test;
		
	--利用数据字典查看同义词synonyms
	--用户创建的同义词有哪些
		select synonym_name
		from user_synonyms;

	--用户有权利查询的同义词有哪些
		select synonym_name
		from all_synonyms;

	--用户有权利查询的同义词有哪些是以字母D开头的
	--注意:表中的数据都是大写存在
		select synonym_name
		from all_synonyms
		where synonym_name like 'D%';
	--结果可以看到我们常用的dual

--8.删除同义词synonym
		drop synonym name;

	--例如:
	--删除私有同义词
		drop synonym my_test;
	--删除公共同义词
		drop public synonym your_test;
	
--9.公共的同义词
	--因为普通用户没有创建public synonym的权限,所有我们需要用dba的身份登录到数据库中去创建。
	--qlplus "/as sysdba"
	--或者system用户登录

		create public synonym your_test
		for test.t_user;

		test.t_user表示的是test用户下面的t_user表

	--让所有人都有查询这个同义词的权限
		grant select on your_test to public;

	--然后其他用户登录之后就可以通过这个公共的同义词来查询test用户下面的t_user表了
		
--10,数据库的导入导出
	--系统终端执行
		  导出:exp   根据提示按回车下一步即可
		  导入:imp	  根据提示按回车下一步即可

本文地址:https://blog.csdn.net/Utaha_/article/details/108570208