java基础面试题——以后找工作就靠它了
mhr18 2024-10-17 10:30 19 浏览 0 评论
1、abstract class和interface有什么区别?
答:声明方法的存在而不去实现它的类被叫做抽象类。接口是抽象类的变体。
2、String, StringBuffer StringBuilder的区别?
答:String是不可变的;StringBuffer是可变的,如果你对字符串中的内容经常进行操作,特别是内容要修改时,那么使用StringBuffer。StringBuilder是从 JDK 5 开始提供的类,通常应该优先使用 StringBuilder 类,因为它支持所有相同的操作,但由于它不执行同步,所以速度更快。
3、重写和重载的区别?
重写:发生在父子类之间,方法名相同,参数的类型、个数、顺序相同,返回值相同,访问权限不能更封闭,抛出异常不能宽泛;
重载:发生在同一个类中,方法名相同,但是参数不同(类型不同或个数不同或参数的顺序不同),返回值可以不相同。
4、接口是否可继承接口? 抽象类是否可实现接口? 抽象类是否可继承实体类?
答:接口是可以继承接口的并且可以继承多个其它接口;抽象类可以实现接口中的方法;抽象类可以继承实体类。
5、面向对象的特征有哪些方面?
答:1)抽象2)继承3)封装4)多态性
6、构造器Constructor是否可以被继承?是否可以被Override?
答:构造器Constructor不能被继承,因此不能重写Overriding,但可以被重载Overloading。
7、Error和Exception有什么区别?
答:error表示系统级的错误和程序不必处理的异常,是恢复不是不可能但很困难的情况下的一种严重问题;比如内存溢出,不可能指望程序能处理这样的情况;
exception表示需要捕捉或者需要程序进行处理的异常,是一种设计或实现问题;也就是说,它表示如果程序运行正常,从不会发生的情况。
8、常见异常有哪些?
NullPointerException:当操作一个空引用时会出现此错误。 NumberFormatException:数据格式转换出现问题时出现此异常。 ClassCastException:强制类型转换类型不匹配时出现此异常。 ArrayIndexOutOfBoundsException:数组下标越界
9、创建多线程有几种方法?实现同步有几种方法,都是什么?哪种效率更高?
答:1、继承Thread类2、实现Runnable接口。
synchronized关键字,一种是同步方法,另一种是同步代码块。锁代码块效率更高。
10、阻塞一个线程都有哪些方法?分别有什么区别?
答:sleep()和wait()。
sleep是线程类(Thread)的方法,wait是Object类的方法。
sleep导致此线程暂停执行指定时间,到时后会自动恢复;wait方法导致本线程放弃对象锁,只有调用notify方法,本线程才进入运行状态。
11、同步和异步有何异同?
同步:上公交,排队
异步:同时运行,互不干扰
12、阐述一下Collection接口包含哪些子集?分别有什么区别?实现类分别是什么?
list和set。List:有序,可重复。Set:无序不可重复
list实现类:ArrayList----按顺序存放数据的数组 LinkedList-----按顺序存放数据的链表
Set实现类: HashSet----根据HashCode()和equals()方法来判断是否有重复TreeSet------通过实现Comparable和Comparator接口而具有排序功能的集合
13、什么是Map?实现类是什么?有什么区别?
Map中存放是Key和value的键值对。实现类是HashMap(查询速度快,非线程安全的)和TreeMap(查询速度慢,元素的排列顺序是不固定的)和Hashtable(线程安全的,效率慢)。
14、Java中都有哪些设计模式:
Factory(工厂模式),Singleton(单例模式),Proxy(代理模式)等。
15、JAVA中常用的XML解析技术有哪些?区别是什么?
答: DOM、SAX 两种方式。
DOM:处理大型文件时其性能下降的非常厉害。
SAX:SAX是事件驱动型的XML解析方法。
16、什么是HTML?
超文本标记语言。
17、文本元素包括什么?
标题元素 段落元素 列表元素 分区元素 行内元素
18、什么是Servlet?什么是JSP?有什么区别和联系?
Servlet是Java平台上的CGI技术。
JSP是一种实现普通静态HTML和动态页面输出混合编码的技术。
20、JAVA中如何进行事务的处理?
setAutoCommit:设置是否自动提交事务,默认为自动提交事务,即为true。
commit():提交事务;
rollback():回滚事务。
21、input标签都有哪些属性?
name,value,type,
22、什么是JavaScript?
JavaScript是嵌入式HTML中浏览器中的脚本语言。
23、JS如何获取对象?
1.document.getElementById
2.document.getElementByName
26、JSP有哪些指令?
1.page指令导包用 2.include指令jsp加载调用文件用 3.taglib指令
27、JSP页面中的Java代码写在哪?
-jsp表达式 -jsp小脚本 -jsp声明
28、JSP的内置对象及方法
request、response、out、pageContext网页属性、Session、applicaton上下文、
config、page 、exception
29、说出Servlet的生命周期?
1、实例化2、初始化,调用init方法3、调用service方法4、销毁调用其destroy方法。
30、什么是Ajax?
Ajax是一种用来改善用户体验的技术,其实质是,使用XMLHttpRequest对象异步地向服务器发请求。
31、发送异步请求的步骤?了解
1.获取ajax对象 2.设置回调函数 3.创建请求 4.发送请求
32、什么是json?
Json是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。Json完全独立于语言之外,但语法上借鉴了JS。
33、String中常用的方法?
IndexOf、substring、trim、charAt、valueOf
34、String 和StringBuffer的区别?
String是final的,提供了数值不可改变的字符串。StringBuffer类提供的字符串进行修改。当你知道字符数据要改变的时候你就可以使用StringBuffer。
35、StringBuffer和StringBuilder的区别?
StringBuffer支持并发操作,线程安全的,适合多线程使用。
StringBuilder线程不安全,但其在单线程中性能比StringBuffer高。
36、StringBuilder类的常用方法?
append():追加字符串insert():插入字符串
delete():删除字符串 replace():替换字符串
reverse():字符串反转
37、启动一个线程是用run()还是start()?
启动一个线程是调用start()方法。
38、部署一个web应用的步骤是什么?
答:1.将web应用放到Tomcat服务器的Webapps包下,
2.启动服务器
3.在地址栏中输入http://localhost:8080/应用名/
39、forward 和redirect的区别?
forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器,浏览器根本不知道服务器发送的内容是从哪儿来的,所以它的地址栏中还是原来的地址。
redirect就是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址,一般来说浏览器会用刚才请求的所有参数重新请求,所session,request参数都可以获取。
41、abstract的method是否可同时是static,是否可同时是synchronized?
都不能
42、数组有没有length()这个方法? String有没有length()这个方法?
数组没有length()这个方法,有length的属性。String有length()这个方法。
43、构造器Constructor是否可被override?
构造器Constructor不能被继承,因此不能重写,但可以被重载。
44、char型变量中能不能存贮一个中文汉字?为什么?
能够定义成为一个中文的,因为java中以unicode编码,一个char两个字节占16位,所以放一个中文是没问题的
45、页面间对象传递的方法
request,session,application,cookie等
46、java中实现
方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。
47、什么是java序列化,如何实现java序列化? 了解
序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操作时所引发的问题。
48、是否可以从一个static方法内部发出对非static方法的调用?
不可以,如果其中包含对象的method();不能保证对象初始化.
49、说出一些常用的类,包,接口,请各举5个
常用的类:BufferedReader BufferedWriter FileReader FileWirter String Integer
常用的包:java.lang java.awt java.io java.util java.sql
常用的接口:Remote List Map Document NodeList
50、在一个千万级的数据库查寻中,如何提高查询效率?
a. 对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。
b. 应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,可以在 num 上设置默认值 0,确保表中 num 列没有 null 值,
c. 并不是所有索引对查询都有效,SQL 是根据表中数据来进行查询优化的,当索引列有大量数据重复时,查询可能不会去利用索引
d. 避免频繁创建和删除临时表,以减少系统表资源的消耗。
e. 应尽量避免在 where 子句中使用!=或<>操作符、使用 or 来连接条件,否则将引擎放弃使用索引而进行全表扫描。
f.尽量不要使用模糊查询
g. 任何地方都不要使用 select * from t ,用具体的字段列表代替“*”。
51、什么是 SpringAOP 和Spring IOC?
AOP:面向切面,调用者和被调用者之间的解耦
IOC:控制反转,控制指的就是程序相关类之间的依赖关系
5).Dispathcher 查询一个或多个 ViewResolver 视图解析器,找到 ModelAndView 对象指定的视图对象
6).视图对象负责渲染返回给客户端。
53、get 和 post 的区别?
1)Get 是用来从服务器上获得数据,而 Post 是用来向服务器上传数据;
2)Get 是不安全的,因为在传输过程,数据被放在请求的 URL 中;Post 的所有操作对用户来说都是不可见的;
3)Get 传输的数据量小,这主要是因为受 URL 长度限制;而 Post 可以传输大量的数据,所以在上传文件只能使用 Post;
55、写一个子查询?
select * from emp where sal>(select avg(sal) from emp group by empno)
56、模糊查询使用什么关键字?
like
57、数据库中用于累加的函数是什么?
sum和count
58、数据库中排序用什么?分组用什么?
order by 、group by
59、说出几个数据库常用的约束?
主键、外键、唯一、非空、检查
60、java和数据库中分别怎么格式化日期?
Java中:Simpledateformate类的 formate方法
数据库中:to_char或者to_date
61、怎么去除字符串的重复信息?
distinct
62、举出几个常用的聚合函数?
avg()、sum()、count()、max()、min()
63、修改表结构,添加一列信息?
alter table emp add(empno number(2));
64、修改表结构,删除一列信息?
alter table emp drop(empno);
65、如何进行分页?
使用rownum伪列
Select rownum,id,name from account where rownum<=3;
66、举出几个常用的IO流?
低级流:字节流FileInputStream、FileOutputStream
高级流:字符流、BufferedWriter、BufferedReader、PrintWriter
63、创建对象有哪几种方式?
4种:1、用new语句创建对象2、运用反射newInstance()方法
3、调用对象的clone()方法4、运用反序列化调用readObject()方法。
64、怎么引入一个js文件?怎么引入一个css文件?
在script中使用Src,使用link
65、什么是el表达式?
是一套简单的计算规则,用于给JSP标签的属性赋值,
也可以直接输出。
66、什么是MVC?MVC分别代表什么?
M——model——模型(封装业务逻辑)
V——view——视图(实现表示逻辑)
C——controller——控制器(协调模型和视图)
67、使用MVC的目的是什么?优点,缺点各是什么?
使用MVC思想来设计软件,最根本的目的是为了实现模型的复用。
1)优点:①可以实现模型的复用。
②模型或者视图发生改变,不会相互影响。
③方便测试(比如,将业务逻辑写在Java类q2`1`1``1`1```里面,可以直接测试,如果写在Servlet里面,必须要先部署才能测试)。
2)缺点:使用MVC后,①会增加设计的难度。
②代码量也会增加。③相应地也会增加软件的开发成本。
68、什么是状态管理?
将浏览器与Web服务器之间多次交互当作一个整体来看待,并且将多次交互所涉及的数据保存下来。
69、什么是JSON?
是一种轻量级的数据交换技术规范。
数据转换:将数据转换成一种中间的,与平台无关的
数据格式(比如Xml或者JSON字符串)发送给另外一方来处理。
70 jdbc
Connection、Statement、PreparedStatement、ResultSet
过程:1、加载驱动2、建立连接3、创建Statement4、执行sql语句5、处理结果集6、关闭连接
在jdbc中事务默认提交 jdbc实现分页 利用oracle的rownum mysql的limit
select * from
(select rownum rn, empno, ename, job,mgr, hiredate, sal, comm, deptno from (select * from emp order by empno))
where rn between 6 and 10;
select * from emp order by empno limit 5,5;
dao接口定义了应用程序中会用到的所有事务方法
到接口还需要有一个实现类,实现接口对应的方法和数据库直接交互
dao包括一个工厂类,一个dao接口,一个接口实现类,数据传递对象
实体对象与一个mapper.xml文件映射,表中字段和类的属性对应,记录和对象对应
71 html
是部署在服务器上的文本文件 根据http协议,浏览器发送请求给服务器,服务器作出响应,给浏览器返回一个html 浏览器解释执行html,显示内容,部署在服务器,运行在浏览器
html 超文本标记语言,一种纯文本类型的语言,可以嵌套脚本语言编写程序段,如javascript
72 css
指层叠样式表 样式定义如何显示HTML元素 样式通常存储在样式表中
内联方式 内部样式表 外部样式表
73 javascript
JavaScript是嵌入式HTML中浏览器中的脚本语言。具有与java和c语言类似的语法,一种网页编程技术,用来向html页面添加交互行为,直接嵌入html页面,由浏览器解释执行代码,比进行预编译
事先不编译,逐行执行,内置大量线程对象
时间定义式 嵌入式 文件调用式
内置对象 String Number Boolean Array Math Date RegExp Function
外部对象 window对象 dom对象
自定义对象
74 jquery
jQuery如何获取对象?
$("#id")
jQuery是一个优秀的JavaScript框架,一个轻量级的JS库,它封装了JS、CSS、DOM,提供了一致的、简洁的API。
引入jquery的js文件 使用选择器定位要操作的节点 调用jquery的方法进行操作$("#di") $("div")
jquery对象本质上十一个dom对象数组,它在该数组上扩展了一些操作数组中元素的方法,可直接操作这个数组 obj.length obj.get(index) obj[index]
dao对象可以直接转换为jquery对象 $(dom对象)
75 servlet
客户端+应用服务器+db
移植性好,适合大型应用
扩展web服务器功能的组件规范 实现servlet接口或继承HttpServlet的java类
当web容器收到一个http请求时通信数据由web容器负责封装和提供,这些信息被解释为两个对象 与请求数据对应的是HttpServletRequest类型对象,与相应数据对应的是HttpServletResponse类型对象
运行步骤 浏览器依据ip建立与容器的连接 浏览器请求数据打包 容器请求数据包,封装对象 容器依据路径找到servlet创建对象 容器调用servlet
对象的service方法 容器将相应打包发送给浏览器 浏览器去除结果生成页面
76 jsp
服务器端动态页面技术的组件规范,是以一个以.jsp为后缀的文件,内含html和少量java代码,jsp会被容器转换为一个servlet类,然后执行,jsp页面中的html包括:html标记 css javascript,像编写html页面一样编写即可 out.write转译
代码包含三种 jsp表达式 jsp小脚本 jsp声明 作用 控制页面中可变的内容产生<%=.....%>out.print语句输出该变量,表达式,方法的值
77 状态管理
客户端状态管理技术:将状态保存在客户端,代表性是cookie技术
浏览器向web服务器发请求时,服务器将少量的数据以set-cookie消息头的方式发送给浏览器,浏览器江浙写数据保存下来,当浏览器再次访问服务器时,会将这些数据以cookie消息头方式发送给服务器
Cookie c=new Cookie(String name,String value);response.addCookie(c);
默认情况下,浏览器会将Cookie保存在内存中,浏览器不关闭,他就一致存在
cookie缺点:可以被用户禁止,状态保存在浏览器端 不安全 对于敏感数据需要加密后再使用cookie来保存,只能村少量数据 4kb左右,有个数限制,只能保存字符串
服务器状态管理技术:将状态保存在服务器端,代表性是session技术
浏览器访问web服务器时,服务器会为每一个浏览器在服务器端的内存中分配空间,单独创建一个Session对象,该对象有一个id属性,值唯一,一般称为SessionId(使用cookie方式)发送给浏览器,浏览器再次访问服务器时,会将sessionid发送给服务器,服务器可以依据sessionid找到对应的srssion对象
HttpSession s=request.getSession(boolean flag);
-------
Session.setAttribute()先绑定数据
Session.getAttribute()读取绑定值,如果没有则跳转登录页面
web服务器会将空闲时间过长的Session对象删除掉,以节省服务器内存空间资源,一般是30分钟 <session-timeout>30</>
浏览器在默认情况下,会使用Cookie方式将Sessionid发送给浏览器,如果用户禁止cookie,则sessionid不会被浏览器保存,此时,服务器可以使用如urt重写这样的方式来发送sessionid
优缺点:安全 保存的数据类型丰富 保存较多数据
但是将状态保存在服务器端,占用服务器的内存,如果用户量过大,会严重影响服务器性能
78 过滤器
编写一个java类,实现Filter接口
在doFilter方法中实现拦截处理逻辑
把过滤器添加到web程序中
把过滤器和web应用一起打包部署
79 监听器
Servlet规范中定义的一种特殊的组件,用来监听Seevlet容器产生的事件并进行相应的处理,容器产生两大类事件 声明周期相关事件 绑定数据相关事件
编写一个java类,依据监听的事件类型选择实现相应的监听器接口HttpSessionListener
在监听器接口方法中,实现相应的监听处理逻辑
在web.xml文件中注册该监听器
80 el表达式
EL表达式是一套简单的计算规则,用于给jsp标签的属性赋值,也可以直接用来输出,表达式可以脱离标签单独使用
分类:访问Bean的属性 输出简单运算结果 获取请求参数值
${对象名.属性名} ${对象名["属性名"]}
81 JSTL
jsp标签库 <c:if>、<c:choose>、<c: when>、<c: otherwise>、<c:forEach>、<c:set>。
82 spring
是一个开源的轻量级应用开发框架,用于简化企业级应用程序开发,降低侵入性,提供的IOC和AOP功能可以将组件的耦合度降到最低,即解藕,便于系统日后的维护和升级。
在spring中 任何的java类和javabean都被当成bean处理,这些bean通过容器管理和使用,机制可以简化bean对象创建和bean对象之间的解藕,有beanFactory和ApplicatyionContext两种类型
实例化ApplicationContext继承自BeanFActory接口
Bean的实例化三种
构造器实例化
静态工厂实例化
实例工厂实例化
83 IOC
被翻译为控制反转 指程序中的获取方式发生反转由最初的new方式创建,转为由第三方框架创建,注入DI 降低对象之间耦合度
spring容器采用DI方式实现了IOC控制,IOC是Spring
kuangjia 的基础和核心
DI被翻译为依赖注入
原理就是将一起工作具有关系的对象通过构造方法参数或方法参数传入建立连接,因此容器的工作就是创建bean时注入那些依赖关系
IOC是一种思想而DI是实现IOC的主要技术途径
DI有两种方式注入:Setter注入和构造器注入
84 自动装配
springIoc容器可以自动装配(autowire)相互协作bean之间的关联关系,autowire的方便指出在于减少xml的注入配置,在xml配置文件中,可以在<bean/>元素中使用
85参数值注入
注入基本值 注入bean对象 注入集合 注入参数值 注入spring表达式 注入表达式 注入null或空字符串
86 组件扫描
指定一个包路径,Spring会自动扫描该包及其子包所有组件类,当发现组件类定义前有特定的注解标计时,就将该组件纳入spring容器,等价于原有xml配置中<bean>定义功能
组件扫描可以替代大量xml配置的<bean>定义
@Component 通用
@Named 通用
@Repository 持久化组件扫描
@Service 业务层组件扫描
@Controller 控制层
@Autowire
@Qulifier自动装配
87 springmvc
1).spring mvc 请所有的请求都提交给 DispatcherServlet,它会委托应用系统的其他模块负责负责对请求进行真正的处理工作。
2).DispatcherServlet 查询一个或多个 HandlerMapping,找到处理请求的 Controller.
3).DispatcherServlet 请请求提交到目标 Controller
4).Controller 进行业务逻辑处理后,会返回一个 ModelAndView
88 springmvc和jdbc
创建工程 搭建Springmvc和jdbc技术环境
编写和配置Springmvc主要组件,例如Controller,HandlerMapping,ViewResolver等
编写JSP视图组件,利用标签和表达式显示模型数据
测试程序
89 mybatis
是支持普通sql查询,存储过程和高级映射的优秀持久层框架 封装了几乎所有的jdbc代码和参数的手工设置以及结果集的检索 使用简单的xml或注解做配置和定义映射关系 将java的POJOs映射成数据库中的记录
结构
加载配置 sql解析 sql执行 结果映射
环境 开发包和数据库驱动包 在src下添加配置文件 指定数据库连接 获取SqlSession实例
90 ajax
异步的javascript和xml
是一种用来改善用户体验的技术,其实质是使用XMLHttpRequest对象异步的向服务器发送请求 服务器返回部分数据,而不是一个完整的页面,以页面无刷新的效果更改页面中局部的内容
发送异步请求步骤
获取ajax对象:获取XMLHttpRequest对象实例
设置回调函数:为ajax对象的onreadystatechange事件设定响应函数
创建请求:调用XMLHttpRequest对象的open方法
发送请求:调用ajax对象的send方法
91 xml和html区别
html不区分大小写,xml严格区分
html,如果上下文清楚的显示出段落或者列表键在何处结尾可以省略</p>之类的结束标记,xml是严格树状结构,不可以省略
html可以拥有不带值的属性名,xml必须拥有
xml文档中,空白部分不会被解析器自动删除,html是过滤掉空格
html标签是预定义的,xml标签是免费的,自定义的,可扩展的
html是用来显示数据,xml是用来描述数据,存放数据,所以可作为持久化介质
没有任何行为的xml与html相似,xml不进行任何操作
92 什么是bean
bean是可以将页面的数据通过bean将他们封装起来,有组织数据的作用,如果使用hibernate框架的话,还会村一些映射文件,普通的bean里面,存储一些类的属性,例如User的get()和set()方法
93 statement和preparedStatement的区别
如果sql语句被执行多次选用preparedStatement是最好的,数据库会对sql语句进行预编译,下次执行相同的sql语句时,数据库端不会在进行预编译了,直接用数据库的缓冲区,提高数据库访问效率,如果sql只执行一次以后不再复用,从安全性来看,preparedStatement是通过?来传递参数的,避免了出现sql注入的问题,安全性好。而statement同一个查询只会产生一次网络到数据库的通讯。
94 jsp和servlet区别
jsp是servlet的扩展,本质上是servlet建议方式,更强调应用外表表达,本质上都是java类 不同点在于servlet应用逻辑在java文件中,并且完全从表示层的html李分离出来,jsp是java和html可以组合成一个扩展名为.jsp的文件,jsp侧重于视图,servlet主要控制逻辑
<!-- 组件扫描 -->
<context:component-scan base-package="controller"/>
<!-- 配置mvc注解扫描 让@RequestMapping注解起作用 -->
<mvc:annotation-driven/>
<!-- 配置视图解析器 前缀与后缀-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- 配置连接池 -->
<environments default="environment">
<environment id="environment">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="oracle.jdbc.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:@176.111.2.22:1521:xe" />
<property name="username" value="jsd1703" />
<property name="password" value="jsd1703" />
</dataSource></environment>
</environments>
<!-- 指定映射文件的位置 -->
<mappers>
<mapper resource="entity/EmpMapper.xml" />
</mappers>
</configuration>
<!-- 拦截器配置 -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/><!-- 拦截 **代表可以出现多个/ -->
<bean class="interceptors.SomeInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
1111 oracle
--SQL语句本身是不支持大小写的,每个关键字用
空格隔开。为了增加
--可读性,通常所有关键字全部大写,非关键字全部小写
--SELECT SYSDATE FROM dual
--创建表
CREATE TABLE employee_wangshuang(
id NUMBER(4),
name VARCHAR2(20),
gender CHAR(1) DEFAULT 'M',
birth DATE,
salary NUMBER(6,2) DEFAULT 4000,
jib VARCHAR2(30),
deptno NUMBER(2)
);
--删除表
DROP TABLE employee_wangshuang;
--数据库中所有数据类型的默认值都是`NULL,
--可以在创建表的时候使用DEFAULT关键字
--为字段单独指定默认值。当插入数据是若
--该字段没有指定值,则使用指定的默认值
--作为该字段的值
--字符串的值在数据库中是使用单引号括起
--来的,这一点与java不同,而且字符串的
--值是区分大小写的。
CREATE TABLE employee_wangshuang1(
id NUMBER(4),
name VARCHAR2(20),
gender CHAR(1) DEFAULT 'M',
birth DATE,
salary NUMBER(6,2),
job varchar2(30),
deptno NUMBER(2)
)
DROP TABLE employee_wangshuang1
--NOT NULL约束
--当某个字段使用NOT NULL约束后,该字段
--的值不允许为空
CREATE TABLE employee_w(
id NUMBER(4),
name VARCHAR(20) NOT NULL,
gebder CHAR(1) DEFAULE'M',
birth DATE,
salary NUMBER(6,2),
job VARCHAR(30),
deptno NUMBER(2)
)
查看表结构
DESC+表名
如:
DESC employee_wangshuang1
DESC employee_lbaoshan
修改表
1:修改表名字
2:修改表结构
1:修改表名字
RENAME old_name To new_name
例如
RENAME employee_wangshuang1 To myemp_wangshuang
DESC myemp_wangshuang
2:修改表结构
2.1:添加新字段
2.2:修改现有字段
2.3:删除现有字段
2.1:将myemp表中添加字段hiredate
ALTER TABLE myemp_wangshuang ADD(
hiredate DATE
)
DESC myemp_wangshuang
2.2:修改字段
需要注意,可以修改字段的类型,长度,添加
非空约束或指定默认值,但是这些最好都是在
表中没有数据的时候进行,若表中含有数据,
那么最好不要修改字段类型,修改长度时尽量
增加而不是缩小,否则可能修改失败
ALTER TABLE myemp_wangshuang MODIFY(
job VARCHAR2(40)
)
DESC myemp_wangshuang
2.3:删除表中现有字段
ALTER TABLE myemp_wangshuang DROP(hiredate)
DESC myemp_wangshuang
DML语句,数据操作语言
DML语句是对表中的数据进行操作的,DML
是伴随事务(TCL)的,
包括增,删,改
INSERT语句
INSERT语句用于向表中插入新数据
INSERT INTO myemp_wangshuang(id,name,salary,deptno)
VALUES (1,'王双',1000,10)
SELECT * FROM myemp_wangshuang
SELECT * FROM WWMMYY501816;
插入日期类型数据
可以使用数据库提供的内置函数TO_DATE
将一个字符串按照指定的日期格式转换为
一个DATE类型数据
INSERT INTO myemp_wangshuang(id,name,birth)
VALUES
(3,'王双',TO_DATE('1995-12-05','YYYY-MM-DD')
)
SELECT * FROM myemp_wangshuang
2:UPDATE语句
UPDATE语句通常需要使用WHERE子句添加条件,
这样会将该表中满足条件的记录进行修改,若
不添加条件则整张表所有记录都会修改
UPDATE myemp_wangshuang
SET salary=8000,deptno=20
WHERE id = 1
SELECT * FROM myemp_wangshuang
3:DELETE
DELETE用于将表中记录删除,同样需要使用
WHERE去添加条件,以删除表中满足条件的记录
若不添加,则是清空表操作
DELETE FROM myemp_wangshuang
WHERE name='王双1'
SELECT * FROM myemp_wangshuang
CREATE TABLE emp_ws(
empno NUMBER(4,0),
ename VARCHAR2(10),
job VARCHAR2(9),
mgr NUMBER(4,0),
hiredate DATE,
sal NUMBER(7,2),
comm NUMBER(7,2),
deptno NUMBER(2,0)
);
CREATE TABLE dept_ws(
deptno NUMBER(2,0),
dname VARCHAR2(14 BYTE),
loc VARCHAR(13 BYTE)
);
DROP TABLE dept_ws;
DESC emp_ws
INSERT INTO emp_ws(empno,ename,jod,mgr,hiredate,sal,comm,deptno)
VALUES(7369,'SMITH','CLERK',7902,TO_DATE('1980-12-17','YYYY-MM-DD'),800,NULL,20);
INSERT INTO emp_ws(empno,ename,jod,mgr,hiredate,sal,comm,deptno)
VALUES(7499,'ALLEN','SALESMAN',7698,TO_DATE('1981-2-20','YYYY-MM-DD'),1600,300,30);
INSERT INTO emp_ws(empno,ename,jod,mgr,hiredate,sal,comm,deptno)
VALUES(7521,'WARD','SALESMAN',7698,TO_DATE('1981-2-22','YYYY-MM-DD'),1250,500,30);
INSERT INTO emp_ws(empno,ename,jod,mgr,hiredate,sal,comm,deptno)
VALUES(7566,'JONES','MANAGER',7839,TO_DATE('1981-4-2','YYYY-MM-DD'),2975,NULL,20);
INSERT INTO emp_ws(empno,ename,jod,mgr,hiredate,sal,comm,deptno)
VALUES(7654,'MARTIN','SALESMAN',7698,TO_DATE('1981-9-28','YYYY-MM-DD'),1250,1400,30);
INSERT INTO emp_ws(empno,ename,jod,mgr,hiredate,sal,comm,deptno)
VALUES(7698,'BLAKE','MANAGER',7839,TO_DATE('1-5-1981','dd-mm-yyyy'),2850,NULL,30);
INSERT INTO emp_ws(empno,ename,jod,mgr,hiredate,sal,comm,deptno)
VALUES(7782,'CLARK','MANAGER',7839,TO_DATE('9-6-1981','dd-mm-yyyy'),2450,NULL,10);
INSERT INTO emp_ws(empno,ename,jod,mgr,hiredate,sal,comm,deptno)
VALUES(7788,'SCOTT','ANALYST',7566,TO_DATE('19-4-87','dd-mm-yyyy'),3000,NULL,20);
INSERT INTO emp_ws(empno,ename,jod,mgr,hiredate,sal,comm,deptno)
VALUES(7839,'KING','PRESIDENT',NULL,TO_DATE('17-11-1981','dd-mm-yyyy'),5000,NULL,10);
INSERT INTO emp_ws(empno,ename,jod,mgr,hiredate,sal,comm,deptno)
VALUES(7844,'TURNER','SALESMAN',7698,TO_DATE('8-9-1981','dd-mm-yyyy'),1500,0,30);
INSERT INTO emp_ws(empno,ename,jod,mgr,hiredate,sal,comm,deptno)
VALUES(7876,'ADAMS','CLERK',7788,TO_DATE('23-5-87','dd-mm-yyyy'),1100,NULL,20);
INSERT INTO emp_ws(empno,ename,jod,mgr,hiredate,sal,comm,deptno)
VALUES(7900,'JAMES','CLERK',7698,TO_DATE('3-12-1981','dd-mm-yyyy'),950,NULL,30);
INSERT INTO emp_ws(empno,ename,jod,mgr,hiredate,sal,comm,deptno)
VALUES(7902,'FORD','ANALYST',7566,TO_DATE('3-12-1981','dd-mm-yyyy'),3000,NULL,20);
INSERT INTO emp_ws(empno,ename,jod,mgr,hiredate,sal,comm,deptno)
VALUES(7934,'MILLER','CLERK',7782,TO_DATE('23-1-1982','dd-mm-yyyy'),1300,NULL,10);
INSERT INTO dept_ws(deptno,dname,loc)VALUES(10,'ACCOUNTING','NEW YORK');
INSERT INTO dept_ws(deptno,dname,loc)VALUES(20,'RESEARCH','DALLAS');
INSERT INTO dept_ws(deptno,dname,loc)VALUES(30,'SALES','CHICAGO');
INSERT INTO dept_ws(deptno,dname,loc)VALUES(40,'OPERATIONS','BOSTON');
DELETE FROM dept_ws WHERE loc='NEWbYORK';
SELECT * FROM emp_ws
UPDATE emp_ws SET deptno=50
WHERE ename='SCOTT'
--DQL 语句
查询语句用来检索数据使用
若写 “*”则表示查询所有字段
FROM子句用来指定数据来源的表
SELECT * FROM emp_ws;
SELECT empno,ename,job,sal FROM emp_ws;
SELECT子句中也允许使用函数或表达式,
这样可以将结果查询出来。
查看每个员工的年薪
SELECT ename,sal*12 年薪 FROM emp_ws;
在DQL中使用WHERE子句也可以只查询出
满足条件的记录
查看职位是“CLERK”的员工
SELECT ename,job,sal
FROM emp_ws WHERE job='CLERK';
SELECT ename,job,sal
FROM emp_ws WHERE sal>2500;
字符串函数
SELECT ename,sal FROM emp_ws;
SELECT CONCAT(ename,sal) FROM emp_ws;
SELECT CONCAT(ename||','||sal) FROM emp_ws;
UPPER,LOWER,INITCAP
将字符串转换为全大写,全小写,首字母大写
伪表:DUAL,当查询的内容与任何表没有关系时
可以在FROM子句中查询该表,会查询出一条记录
SELECT UPPER('helloword'),LOWER('HELLOWORD'),INITCAP('hello word')
FROM dual;
TRIM,LTRIM,RTRIM
去除字符串两边指定字符
SELECT TRIM('e' FROM'eeeeeliteeeeeee')
FROM dual;
SELECT TRIM('e' FROM'esesederfeseliteeeeegxxxxxxxxxxeee')
FROM dual;
SELECT LTRIM('essseselit','es')
FROM dual;
SELECT RTRIM('edededhguhuhuh','hu')
FROM dual;
LPAD,RPAD补位函数
允许将指定字符串显示指定位数,不足时补充若干指定字符达到该长度
SELECT ename,RPAD(sal,5,'$')
FROM emp_ws
SELECT ename,LPAD(sal,5,'@')
FROM emp_ws
SUBSTR(str,m[,n])
将给定字符串从m处开始连接截取n个字符
n不指定则是截取到末尾,n超过可以截取
的字符数量也是截取到末尾。
m可以是负数,负数则是从倒数位置开始
数据库中的下标从1开始
SELECT SUBSTR('thinking in java',-5,3)
FROM dual
INSER(c1,c2,m,n)
查看c2在c1中的位置
m是用来指定从哪里开始检索,不写默认从第一个字符开始
n表示第几次出现,不写默认为1
SELECT INSTR('thinking in java','in',4,2)
FROM dual
数值函数
ROUND(m,n):四舍五入
n为保留到小数点后的位数,
若n为负数则是10位以上的数字
SELECT ROUND(55.678,1) FROM dual
SELECT ROUND(55.678,0) FROM dual
SELECT ROUND(55.678,-1) FROM dual
TRUNC(m,n)函数:截取数字
SELECT TRUNC(55.678,1) FROM dual
SELECT TRUNC(55.678,0) FROM dual
SELECT TRUNC(55.678,-1) From dual
MOD(m,n)求余数
SELECT ename, MOD(sal,1000) FROM emp_ws
SELECT MOD(5256,100) FROM dual
CELT,FLOOR向上取整和向下取整
SELECT CEIL(45.678) FROM dual
SELECT FLOOR(45.678) FROM dual
日期相关函数:
和日期相关关键字
SYSDATE:返回一个DATE类型数据,表示当前系统时间
SYSTIMESTAMP:返回一个时间戳类型数据,表示当前系统时间
SELECT SYSDATE FROM dual
SELECT SYSTIMESTAMP FROM dual
TO_DATE函数
将一个字符串按照指定的日期格式解析为DATE
在日期格式字符串中,除英文,数字,符号外的
其他字符都要使用双引号括起来
SELECT TO_DATE('1992-08-03 14:22:15','YYYY-MM-DD HH24:MI:SS')
FROM dual
SELECT TO_DATE('1992年08月03日 14时22分15秒','YYYY"年"MM"月"DD"日" HH24"时"MI"分"SS"秒"')
FROM dual
TO_CHAR函数
可以将一个DATE按照给定的日期格式转换为字符串
SELECT TO_CHAR(SYSDATE,'YYYY-MM-DD HH24:MI:SS') FROM dual
日期类型是可以进行计算的:
1:对一个日期加减一个数字等同与加减天数
2:两个日期相减,差为相差的天数
同样,日期间也可以比较大小,越晚的越大
查看每个员工入职到今天的天数
SELECT ename,SYSDATE-hiredate FROM emp_ws
SELECT ename,CEIL(SYSDATE-hiredate) FROM emp_ws
SELECT SYSDATE+1 FROM dual
SELECT SYSDATE-165 FROM dual
LAST_DAY(date)
返回给定日期所在月的月底日期
当月月底是哪天
SELECT LAST_DAY(SYSDATE) FROM dual
ADD_MONTHS(date,i)
计算指定日期加上指定的月后的日期
若i是负数,则是计算减法
查看每个员工入职20周年纪念日
SELECT ename,ADD_MONTHS(hiredate,12*20) FROM emp_ws
MONTHS_BETWEEN(d1,d2)
计算两个日期之间相差的月
SELECT ename,MONTHS_BETWEEN(SYSDATE,hiredate) FROM emp_ws
NEXT_DAY(date,i)
返回给定日期之后一周内的指定周几的日期
SELECT NEXT_DAY(SYSDATE,1) FROM dual
LEAST,GREATEST函数
求最小值和最大值
SELECT LEAST(SYSDATE,TO_DATE('2008-08-08','YYYY-MM-DD')) FROM dual
SELECT GREATEST(SYSDATE,TO_DATE('2008-08-08','YYYY-MM-DD')) FROM dual
EXTRACT函数,提取指定日期指定时间分量的值
SELECT EXTRACT(YEAR FROM SYSDATE) FROM dual
查看19801年入职的员工?
SELECT ename,hiredate FROM emp_ws
WHERE EXTRACT(YEAR FROM hiredate)=1980
CREATE TABLE student_ws(
id NUMBER(4),
name CHAR(20),
gender CHAR(1)
);
INSERT INTO student_ws VALUES(1000,'王双','F')
INSERT INTO student_ws VALUES(1001,'薛之谦',NULL)
INSERT INTO student_ws(id,name) VALUES(1002,'李荣浩')
UPDATE student_ws SET gender = NULL WHERE id =1000
使用NULL值作为判断条件
将性别为NULL的记录删除
DELETE FROM student_ws WHERE gender IS NULL
DELETE FROM student_ws WHERE gender IS NOT NULL
NULL的运算
NULL与字符串连接等于什么都没做
NULL与数字运算结果还是NULL
查看每个员工的收入(工资+绩效)
SELECT ename,sal,comm ,sal+comm FROM emp_ws
空值函数
NVL(f1,f2)
当f1为NULL时,函数返回f2的值,否则返回f1自身
所以NVL函数的作用是将NULL值替换为非NULL
查看每个员工的收入(工资+绩效)
SELECT ename,sal,comm ,sal+NVL(comm,0) FROM emp_ws
查看绩效情况,有绩效的显示“有绩效”
为NULL的则显示“没有绩效”
NVL2(f1,f2,f3)函数
当f1不为NULL时函数返回f2
当f1为NULL时,函数返回f3
SELECT ename,comm,NVL2(comm,'有绩效','没有绩效') FROM emp_ws
SELECT ename,sal,comm,NVL2(comm,sal+comm,sal) FROM emp_ws
在SELECT子句中出现的函数或表达式会
在结果集中作为字段名,这样的可读性差
因此可以为这样的字段添加别名
别名中如果是希望包含小写,需要使用双引号括起来
SELECT ename ,sal*12 sal FROM emp_ws;
SELECT ename,sal FROM emp_ws WHERE sal<2000;
SELECT ename,sal,job FROM emp_ws WHERE deptno<>10;
SELECT ename,sal,hiredate FROM emp_ws
WHERE hiredate > to_date('1982-1-1','YYYY-MM-DD');
查询薪水大于1000并且职位是‘CLERK’的职员信息
SELECT ename,sal,job FROM emp_ws
WHERE sal>1000 AND job='CLERK';
查询薪水大于1000或者职位是‘CLERK’的职员信息
SELECT ename,sal,job FROM emp_ws
WHERE sal>1000 OR job='CLERK';
AND,OR
与或用来连接多个条件
AND优先级高于OR,所以可以通过括号
来提高OR的优先级
SELECT ename,sal,job FROM emp_ws
WHERE sal>1000 AND job='CLERK' OR job='SALESMAN';
SELECT ename,sal,job FROM emp_ws
WHERE sal>1000 AND job='SALESMAN' OR job='CLERK';
SELECT ename,sal,job FROM emp_ws
WHERE sal>1000 AND (job='SALESMAN' OR job='CLERK');
LIKE用于模糊匹配字符串
有两个通配符:
_:表示单一的一个字符
%:表示任意个字符(0-多个)
查看名字第二个字母是A第四个字母是T的?
SELECT ename,sal,job FROM emp_ws
WHERE ename LIKE '_A_T%';
SELECT ename,sal,job FROM emp_ws
WHERE ename LIKE '%T';
IN(LIST),NOT IN(LIST)
判断在列表中或不再列表中
SELECT ename,job FROM emp_ws
WHERE job IN ('MANAGE','CLERK');
SELECT ename,job,deptno FROM emp_ws
WHERE deptno NOT IN (10,20);
BETWEEN...AND...
判断在一个区间范围内
查看工资在1500到3000之间的员工
SELECT ename,sal,deptno FROM emp_ws
WHERE sal BETWEEN 1500 AND 3000;
ANY,ALL通常是联合>,>=,<,<=的判断
并且判断的是多个值
>ANY(list):大于列表之一(大于最小即可)
>ALL(list):大于列表所有(大于最大的)
<ANY(list):小于列表之一(小于最大即可)
<ALL(list):小于列表所有(小于最小的)
他们在子查询的判断中
SELECT ename,sal,deptno FROM emp_ws
WHERE sal>ANY(3500,4000,4500);
SELECT ename,sal,deptno FROM emp_ws
WHERE sal>ALL(3500,4000,4500);
SELECT ename,sal,deptno FROM emp_ws
WHERE sal<ANY(3500,4000,4500);
SELECT ename,sal,deptno FROM emp_ws
WHERE sal<ALL(3500,4000,4500);
查询条件中使用函数
SELECT ename,sal,job FROM emp_ws
WHERE ename = UPPER('scott');
查询条件中使用表达式
SELECT ename,sal,job FROM emp_ws
WHERE sal*12>50000;
DISTINCT关键字
在SELECT子句中使用,用来对指定的字段
值去除重复行
查看公司有哪些职位
SELECT DISTINCT job FROM emp_ws;
多字段去重时,不保证单一的某个字段的
值没有重复,而去重原则是这些字段值的
组合没有重复行
SELECT DISTINCT job,deptno FROM emp_ws;
ORDER BY子句
ORDER BY子句用来排序结果集,该子句
只能写在SELECT语句的最后一个子句上
ORDER BY可以根据给定字段进行升序或者
降序排列结果集。
其中ASC为升序,通常不写,因为默认为升序
DESC为降序
查看公司工资排名
SELECT ename,sal,deptno FROM emp_ws
ORDER BY sal DESC;
SELECT ename,sal,deptno FROM emp_ws
ORDER BY sal ASC;
多字段排序
排序是有优先级的,首先按照内地一个字段的
排序方式对结果集排序,当第一个字段的值相同时
才按照第二个字段的排序方式排序这些记录
SELECT ename,sal,deptno FROM emp_ws
ORDER BY deptno DESC,sal DESC;
SELECT ename,deptno FROM emp_ws
ORDER BY sal DESC;
查看年薪高于20000,并且在10或者20号部门
名字中含有E的员工,按照工资从高到低排列显示
SELECT ename,sal,deptno FROM emp_ws
WHERE sal*12>20000 AND deptno IN(10,20) AND ename LIKE '%E%'
ORDER BY sal DESC;
SELECT ename,sal,deptno FROM emp_ws
WHERE sal*12>20000 AND (deptno=10 OR deptno=20) AND ename LIKE '%E%'
ORDER BY sal;
聚合函数
聚合函数是用来统计数据的
其中包括
MAX,MIN,SUM,AVG,COUNT
MAX,MIN求最大值和最小值
SUN,AVG求总和与平均值
COUNT统计记录数
SELECT MAX(sal),MIN(sal),SUM(sal),AVG(sal) FROM emp_ws;
统计记录数,聚合函数忽略null值
SELECT COUNT(ename) FROM emp_ws;
SELECT AVG(comm),COUNT(comm) FROM emp_ws;
SELECT SUM(comm),AVG(comm),COUNT(comm) FROM emp_ws;
SELECT AVG(NVL(comm,0)) FROM emp_ws;
SELECT * FROM emp_ws;
排序的字段若有null值,则null被认为最大值
SELECT comm FROM emp_ws ORDER BY comm DESC;
当SELECT子句中出现了聚合函数,
那么不是聚合函数的其他单独字段
都必须出现在GROUP BY子句中。
反过来则五要求。
SELECT ename,MAX(sal) FROM emp_ws;
GROUP BY子句
GROUP BY是配合聚合函数使用的
GROUP BY允许将结果集合按照给定字段值
一样的记录进行分组,然后配合聚合函数
对这些分组的记录分别统计结果
查看每个部门的平均工资
SELECT AVG(sal),deptno FROM emp_ws GROUP BY deptno;
查看每种职位的最高与最低工资
SELECT job,MAX(sal),MIN(sal) FROM emp_ws GROUP BY job;
查看平均工资高于2000的那些部门的具体平均工资是多少
SELECT AVG(sal),deptno FROM emp_ws
WHERE AVG(sal)>2000 GROUP BY deptno;
WHERE中不能使用聚合函数当作过滤条件
原因在于过滤的时机不对
WHERE是在检索表中数据的时候进行过滤的,
所以WHERE使用来确定结果集记录数的,而
聚合函数是建立在结果集生成后的数据中进
行统计的,所以使用聚合函数过滤是在WHERE
之后进行的。
HAVING子句
HAVING子句必须出现在GROUP BY子句之后
作用是添加过滤条件来取出不符合的分组。
HAVING中可以使用聚合函数作为过滤条件
SELECT AVG(sal),deptno FROM emp_ws
GROUP BY deptno HAVING AVG(sal)>2000;
SELECT AVG(sal),deptno FROM emp_ws
HAVING AVG(sal)>2000GROUP BY deptno;
查看平均工资高于2000的这些部门的最高工资与最低工资十多少
SELECT MAX(sal),MIN(sal),deptno FROM emp_ws
GROUP BY deptno HAVING AVG(sal)>2000;
查看最低工资高于800的那些部门各多少人
SELECT deptno,COUNT(ename) FROM emp_ws GROUP BY deptno HAVING MIN(sal)>800;
SELECT deptno,COUNT(*) FROM emp_ws GROUP BY deptno HAVING MIN(sal)>800;
关联查询
关联查询指的是数据从多张表中联合
查询,结果集中的字段来自不同表。
关联查询中用于指定表与表的数据的
联系的条件称为关联条件。
通常关联查询中都要写关联条件,因为
不写会产生笛卡尔积,通常情况下都是
无意义的结果集,开销巨大。
查看每个员工的名字以及其所在部门的名称
SELECT ename,dname FROM emp_ws,dept_ws
WHERE emp_ws.deptno=dept_ws.deptno;
SELECT e.ename,d.dname,e.deptno FROM emp_ws e,dept_ws d
WHERE e.deptno=d.deptno;
不满足连接条件的记录是查询不出来的
SELECT e.ename,e.deptno,d.dname FROM emp_ws e,dept_ws d;
N张表关联查询要写至少N-1个连接条件
过滤条件必须与连接条件同时成立
查看在NEW YORK工作的员工都有谁
SELECT e.ename,e.deptno,d.dname,d.loc
FROM emp_ws e,dept_ws d
WHERE e.deptno=d.deptno
AND d.loc='NEW YORK';
查看工资高于2000的员工都有谁?
查看该员工的名字,工资,所在部门名字,以及工作所在地
SELECT e.sal,e.ename,e.deptno,d.dname,d.loc
FROM emp_ws e,dept_ws d
WHERE e.deptno=d.deptno
AND sal>2000;
内连接
内连接也是关联查询的一种
查看每个员工的名字以及其所在部门名?
SELECT e.ename,d.dname
FROM emp_ws e JOIN dept_ws d
ON e.deptno=d.deptno
WHERE d.dname='SALES';
外连接
外连接在关联查询中除了可以将满足连接条件的记录查询出来之外,
还可以将不满足连接条件的记录也查询出来。
外连接分为:
左外连接:以JOIN左侧表作为驱动表(所有记录都显示)那么当该
表记录不满组连接条件时,那么来自右侧表的字段值为null。
右外连接,全外连接
查看每个员工信息
SELECT e.ename,d.dname
FROM emp_ws e LEFT OUTER JOIN dept_ws d
ON e.deptno=d.deptno;
SELECT e.ename,d.dname
FROM emp_ws e RIGHT OUTER JOIN dept_ws d
ON e.deptno=d.deptno;
SELECT e.ename,d.dname
FROM emp_ws e FULL OUTER JOIN dept_ws d
ON e.deptno=d.deptno;
SELECT e.ename,d.dname
FROM emp_ws e JOIN dept_ws d
ON e.deptno=d.deptno(+);左外连接
FROM emp_ws e JOIN dept_ws d
ON e.deptno(+)=d.deptno;右外连接
自连接
自连接即:当前表的记录可以对应当前表
子集的多条记录,这种设计是为了解决记录
属性一样但是又存在父子关系的树状结构数据
时使用
常见的:商品类别
查看员工的名字以及其上司的名字
SELECT e.ename,m.ename
FROM emp_ws e,emp_ws m
WHERE e.mgr=m.empno(+);
SELECT e.ename,m.ename
FROM emp_ws e JOIN emp_ws m
ON e.mgr= m.empno;
SELECT e.ename,m.ename
FROM emp_ws e FULL OUTER JOIN emp_ws m
ON e.mgr= m.empno;
SELECT * FROM dept_ws;
SELECT * FROM emp_ws;
子查询
子查询是一条查询语句,他是嵌套在其他SQL语句当中的,
作用是为外层的SQL提供数据的。子查询常用在查询语句
中,当然也可以用在DML,DDL中
查看与FORD同部门的员工
SELECT ename,sal,deptno
FROM emp_ws
WHERE deptno=(SELECT deptno
FROM emp_ws
WHERE ename='FORD');
SELECT ename,job FROM emp_ws
WHERE job=(SELECT job FROM emp_ws
WHERE ename='SMITH');
查看比公司平均工资高的员工信息
SELECt ename,sal FROM emp_ws
WHERE sal>(SELECT AVG(sal) FROM emp_ws);
在DDL中使用子查询
可以基于一个子查询的结果集当作表快速的创建出来
创建表employee
字段:empno,ename,mgr,sal,job,deptno,dname,loc
数据是基于表中emp,dept现有数据
CREATE TABLE employee_ws AS
SELECT e.empno,e.ename,e.mgr,
e.sal,e.job,d.deptno,d.dname,d.loc
FROM emp_ws e LEFT OUTER JOIN dept_ws d
ON e.deptno=d.deptno;
子查询在DML中的应用
将SMITH所在部门员工工资上浮10%
UPDATE emp_ws
SET sal=sal*1.1
WHERE deptno=(SELECT deptno FROM emp_ws
WHERE ename='SMITH');
子查询根据查询结果不同分为:
单行单列,多行单列:常用在WHERE作为过滤条件
多行多列:长当作表看待
当判断的是一个多行单列的子查询结果时,通常要配合
IN,ANY,ALL使用
查看与职位是SALESMAN同部门的其他职位员工。
SELECT ename,job,deptno
FROM emp_ws
WHERE deptno IN(SELECT deptno
FROM emp_ws
WHERE job='SALESMAN')
AND job<>'SALESMAN';
查看比SALESMAN和CLERK职位工资都高的员工:
SELECT ename,sal FROM emp_ws
WHERE sal>ALL(Select sal FROM emp_ws
WHERE job IN('SALESMAN','CLERK')
);
EXISTS关键字
EXISTS在WHERE中使用,后面跟一个子查询,子查询的结果
不管住具体值,直关注是否能查询出数据,只要可以则条件成立
查看有员工的部门信息
SELECT deptno,dname FROM dept_ws d
WHERE EXISTS(SELECT * FROM emp_ws e
WHERE d.deptno=e.deptno);
SELECT deptno,dname FROM dept_ws d
WHERE NOT EXISTS(SELECT * FROM emp_ws e
WHERE d.deptno=e.deptno);
查询部门的最低薪水,前提是高于30号部门的最低薪水
SELECT MIN(sal),deptno FROM emp_ws
GROUP BY deptno
HAVING MIN(sal)>(SELECT MIN(sal) FROM emp_ws
WHERE deptno=30);
FROM子句中使用子查询
该子查询是当作一张表使用的
查看比自己所在部门平均工资高的员工
SELECT e.ename,e.sal,e.deptno
FROM emp_ws e,
(SELECT AVG(sal) avg_sal,deptno
FROM emp_ws GROUP BY deptno) t
WHERE e.deptno=t.deptno
AND e.sal>t.avg_sal;
SELECT e.ename,e.sal,
(SELECT d.dname FROM dept_ws d
WHERE d.deptno=e.deptno) dname
FROM emp_ws e;
分页查询
分页查询其实就是将数据分段查询出来,当数据量
大的时候经常会使用分页查询计数,这样可以减少
资源开销,提高系统相应速度。
标准SQL中没有定义分页语法,所以不同的数据库
的分页语法不一样。
ORACL中使用伪列ROWNUM实现
ROWNUM是一个伪列,并不存在与任何表中,但是所有的表都可以
查询该字段,而该字段的值就是查询出来的结果集中每条记录的
行号,从1开始自动递增。ROWNUM字段的值生成是伴随查询进行的
过程中的,每当可以从表中查询出一条记录,那么ROWNUM的值就是
该条查询出来记录的行号。
SELECT ROWNUM,ename,sal,deptno FROM emp_ws
WHERE ROWNUM BETWEEN 1 AND 3;
由于ROWNUM的值查询过程中动态生成,并从1开始所以在使用RPWNUM对结果集
编行号时不要使用ROWNUM在WHERE中做>1以上数字的判断,否则查不到任何数据。
SELECT ROWNUM,ename,sal,deptno
FROM emp_ws WHERE ROWNUM >1;
SELECT * FROM(SELECT ROWNUM rn,
ename,sal,deptno FROM emp_ws)
WHERE rn BETWEEN 6 AND 10;
SELECT * FROM(SELECT ROWNUM rn,t.*
FROM(SELECT ename,sal,deptno
FROM emp_ws ORDER BY sal DESC) t
)
WHERE rn BETWEEN 6 AND 10;
SELECT *
FROM(SELECT ROWNUM rn,t.*
FROM(SELECT ename,sal,deptno
FROM emp_ws
ORDER BY sal DESC) t
WHERE ROWNUM<=10)
WHERE rn>=6;
pageSize(每页显示的条目数):5
page(页数):2
start:(page-1)*pageSize+1
end:pageSize*page
DECODE函数,可以实现简单的分支结构
SELECT ename,job,sal,
DECODE(job,
'MANAGE',sal*1.2,
'ANALYST',sal*1.1,
'SALESMAN',sal*1.05,
sal
) bonus
FROM emp_ws;
SELECT ename,job,sal,
CASE job WHEN 'MANAGER'THEN sal*1.2
WHEN 'ANALYST'THEN sal*1.1
WHEN 'SALESMAN' THEN sal*1.05
ELSE sal END
bonus
FROM emp_ws;
SELECT
COUNT(1),DECODE(job,
'MANAGER','VIP',
'ANALYST','VIP',
'OTHER')
FROM emp_ws
GROUP BY DECODE(job,
'MANAGER','VIP',
'ANALYST','VIP',
'OTHER');
SELECT deptno,dname,loc
FROM dept_ws
ORDER BY
DECODE(dname,'OPERATIONS',1,
'ACCOUNTING',2,'SALES',3);
排序函数
排序函数允许对结果集按照指定字段分组
然后在组内按照指定字段排序,之后为每
组的记录编行号
ROW_NUMBER():生成组内连续且唯一的数字
查看每个部门的工资排名:
SELECT ename,job,deptno,
ROW_NUMBER() OVER(
PARTITION BY deptno
ORDER BY sal DESC
) rank
FROM emp_ws;
RANK函数:组内不连续不唯一的数字
SELECT
ename,sal,deptno,
RANK() OVER(
PARTITION BY deptno
ORDER BY sal DESC
) rank
FROM emp_ws;
DENSE_RANK:生成组内连续但不唯一的数字
SELECT
ename,sal,deptno,
DENSE_RANK() OVER(
PARTITION BY deptno
ORDER BY sal DESC
) rank
FROM emp_ws;
CREATE TABLE sales_tabws(
year_id NUMBER NOT NULL,
month_id NUMBER NOT NULL,
day_id NUMBER NOT NULL,
sales_value NUMBER(10,2) NOT NULL
);
INSERT INTO sales_tabws
SELECT TRUNC(DBMS_RANDOM.value(2010,2012))AS year_id,
TRUNC(DBMS_RANDOM.value(1,13)) AS month_id,
TRUNC(DBMS_RANDOM.value(1,32)) AS day_id,
ROUND(DBMS_RANDOM.value(1,100),2)AS sales_value
FROM dual
CONNECT BY level<=1000;
SELECT ename,job,sal FROM emp_ws
WHERE job ='MANAGER'
UNION
SELECT ename,job,sal FROM emp_ws
WHERE sal>2500;
SELECT ename,job,sal FROM emp_ws
WHERE job='MANAGER'
UNION ALL
SELECT ename,job,sal FROM emp_ws
WHERE sal>2500;
SELECT ename,job,sal FROM emp_ws
WHERE job = 'MANAGER'
INTERSECT
SELECT ename,job,sal FROM emp_ws
WHERE sal>2500;
SELECT ename,job,sal FROM emp_ws
WHERE job = 'MANAGER'
MINUS
SELECT ename,job,sal FROM emp_ws
WHERE sal>=2500;
高级分组函数
1:ROLLUP
GROUP BY ROLLUP(a,b,c)
等价于
GROUP BY a,b,c
UNION ALL
GROUP BY a,b
UNION ALL
GROUP BY a
UNION ALL
全表
SELECT
year_id,month_id,day_id,SUM(sales_value)
FROM
sales_tabws
GROUP BY
ROLLUP(year_id,month_id,day_id)
ORDER BY year_id,month_id,day_id;
CUBE()函数
CUBE的分组次数是2的参数个数次方
每一种组合都会进行一次分组
SELECT
year_id,month_id,day_id,SUM(sales_value)
FROM
sales_tabws
GROUP BY
CUBE(year_id,month_id,day_id)
ORDER BY year_id,month_id,day_id;
GROUPING SETS 函数
该函数允许自定义分组模式,然后将这些分组结果
并在一个结果集显示,其中每个参数为一种分组模式。
查看每天与每月的营业额?
SELECT year_id,month_id,
day_id,SUM(sales_value)
FROM sales_tab
GROUP BY GROUPING SETS((year_id,month_id,day_id),(year_id,month_id));
数据库对象
数据库对象包含:表,视图,索引,序列
视图VIEW
视图在SQL语句中体现的角色与表一样,但是视图并非真实
存在的表,它只是对应一条查询语句的结果集。
使用视图通常是为了重用子查询,简化SQL语句的复杂度和限制
某些语句的访问。
创建一个包含10号部门员工信息的视图。
CREATE VIEW v_emp_10ws AS
SELECT empno,ename,sal,job,deptno
FROM emp_ws WHERE deptno=10;
DESC v_emp_10ws;
SELECT * FROM v_emp_10ws;
视图中对应的子查询中若含有函数或表达式,那么该字段
必须给别名,并且字段的别名会称为该视图对应字段的名字。
CREATE OR REPLACE VIEW v_emp_10ws AS
SELECT empno id,ename name,sal salary,job,deptno
FROM emp_ws WHERE deptno=10;
DESC v_emp_10ws;
SELECT * FROM v_emp_10ws;
针对视图的DML操作
复杂视图不能进行DML操作
对简单视图进行DML操作就是对该视图数据
来源的基础表进行的
INSERT INTO v_emp_10ws
(id,name,salary,job,deptno)
VALUES (1001,'JACK',2000,'CLERK',10);
UPDATE v_emp_10ws SET salary=3000 WHERE name='JACK';
DELETE FROM v_emp_10ws WHERE name='JACK';
对视图进行DML操作是可能会污染基础表数据
即:对视图进行DML操作后,视图对该数据不可见。
INSERT INTO vempws(id,name,salary,job,deptno)
VALUES (1001,'JACK',2000,'CLERK',20);
UPDATE v_emp_10ws SET deptno=20;
删除不会污染
DELETE FROM v_emp_10ws WHERE deptno=20;
SELECT * FROM v_emp_10ws;
SELECT * FROM emp_ws;
为了避免不当的DML操作会污染基表,可以为视图添加检查选项:
WITH CHECK OPTION
当视图添加了该选项后,那么对视图进行DML操作时,
视图会检查执行该操作后视图是否对操作的记录可见,
不可见则不允许该DML操作。
CREATE OR REPLACE VIEW v_emp_10ws
AS SELECT empno id,ename name,sal salary,job,deptno
FROM emp_ws WHERE deptno=10
WITH CHECK OPTION;
为视图添加只读选项后,该视图不允许进行DML操作
CREATE OR REPLACE VIEW v_emp_10ws
AS SELECT empno id,ename name,sal salary,job,deptno
FROM emp_ws WHERE deptno=10
WITH READ ONLY;
数据字典可以查看用户创建的数据库对象信息
SELECT object_name,object_type
FROM user_objects;
SELECT object_name,object_type
FROM user_objects
WHERE object_name LIKE '%_WS';
SELECT view_name,text FROM user_views;
SELECT table_name FROM user_tables;
创建复杂视图
当视图对应的SQL语句含有函数,表达式分组,
去重或关联查询时,该视图为复杂视图。
复杂视图不允许进行DML操作
创建一个含有每个部门薪资情况视图
SELECT
MAX(e.sal) max_sal,MIN(e.sal) min_sal,
AVG(e.sal) avg_sal,SUM(e.sal) sum_sal,
d.deptno,d.dname FROM emp_ws e,dept_ws d
WHERE e.deptno=d.deptno GROUP BY d.deptno,d.dname;
查看谁的工资高于所在部门的平均工资
SELECT e.ename,e.sal,e.deptno
FROM emp_ws e,v_dept_sal v
WHERE e.deptno = v.deptno
AND e.sal>v.avg_sal;
删除视图
DROP VIEW v_emp_10ws;
序列
序列也是数据库对象之一
序列的作用是生成一系列的数字
通常使用序列是为表的主键(ID)字段提供值
创建一个序列
CREATE SEQUENCE seq_emp_idws
START WITH 1
INCREMENT BY 1;
序列提供了两个伪列用于取数字
NEXTVAL:获取序列下一个数字
序列会根据序列最后生成的数字加上步长来得到。
NEXTVAL回到值序列步进。
序列是不能回退的,发生步进后之前的数字就无法再次获取
CURRVAL:获取序列最后生成的数字
在使用CURRVAL之前应至少调用过一次NEXTVAL后才可以使用
SELECT seq_emp_idws.NEXTVAL FROM dual;
SELECT seq_emp_idws.CURRVAL FROM dual;
使用seq_emp_idws为emp_ws表提供主键值:
INSERT INTO emp_ws
(empno,ename,job,sal,deptno)
VALUES (seq_emp_idws.NEXTVAL,'JACK','CLERK',2000,10);
SELECT * FROM emp_ws;
删除序列
DROP SEQUENCE seq_emp_idws;
INDEX索引
索引是为了提高查询效率
索引的实现是数据库内部完成
CREATE INDEX idx_emp_ws_ename ON emp_ws(ename);
SELECT * FROM emp_ws;
多列索引
CREATE INDEX idx_emp_ws_job_sal
ON emp_ws(job,sal);
函数添加索引
CREATE INDEX emp_ws_ename_upper_idx
ON emp_ws(UPPER(ename));
SELECT *FROM emp_ws
WHERE UPPER(ename)='KING';
重建索引
ALTER INDEX idx_emp_ws_ename REBUILD;
删除索引
DROP INDEX idx_emp_ws_ename;
约束
CREATE TABLE employees_ws(
eid NUMBER(6),
name VARCHAR(30) NOT NULL,
salary NUMBER(7,2),
hiredate DATE
CONSTRAINT employees_ws_hiredate_nn NOT NULL
);
修改表是添加非空约束
可以在建表之后,通过修改表的定义,添加非空约束
ALTER TABLE employees_ws
MODIFY(eid NUMBER(6) NOT NULL);
取消非空约束
如果业务要求取消某列的非空约束,可以采用重载表或者修改表的方式
ALTER TABLE employees_ws
MODIFY (eid NUMBER(6) null);
DESC employees_ws;
唯一性约束
唯一性约束可以保证字段的值在整张表
中每条记录都不一样,NULL除外。
CREATE TABLE employees1_ws(
eid NUMBER(6) UNIQUE,
name VARCHAR(30),
email VARCHAR2(50),
salary NUMBER(7,2),
hiredate Date,
CONSTRAINT employees1_ws_email_uk UNIQUE(email));
INSERT INTO employees1_ws
(eid,name,email)
VALUES
(1,'JACK','JACK@tedu.cn');
INSERT INTO employees1_ws
(eid,name,email)
VALUES
(null,'JACK',null);
SELECT * FROM employees1_ws
添加唯一性约束
在建表之后增加后唯一性约束条件:
ALTER TABLE employees1_ws
ADD CONSTRAINT employees1_ws_name_uk UNIQUE(name);
主键约束
非空且唯一,且一张表只能有一个字段添加主键约束
CREATE TABLE employees2_ws(
eid NUMBER(6) PRIMARY KEY,
name VARCHAR(30),
email VARCHAR(50),
salary NUMBER(7,2),
hiredate DATE
);
INSERT INTO employees2_ws
(eid,name) VALUES (1,'JACK');
不可以为空
INSERT INTO employees2_ws
(eid,name) VALUES (null,'JACK');
检查约束
ALTER TABLE employees2_ws
ADD CONSTRAINT employees2_ws_salary_check
CHECK(salary>2000);
INSERT INTO employees2_ws(eid,name,salary)
VALUES(1236,'donna noble',2500);
UPDATE employees2_ws SET salary =1500
WHERE eid =1236;
相关推荐
- 【预警通报】关于WebLogic存在远程代码执行高危漏洞的预警通报
-
近日,Oracle官方发布了2021年1月关键补丁更新公告CPU(CriticalPatchUpdate),共修复了包括CVE-2021-2109(WeblogicServer远程代码执行漏洞)...
- 医院信息系统突发应急演练记录(医院信息化应急演练)
-
信息系统突发事件应急预案演练记录演练内容信息系统突发事件应急预案演练参与人员信息科参与科室:全院各部门日期xxxx-xx-xx时间20:00至24:00地点信息科记录:xxx1、...
- 一文掌握怎么利用Shell+Python实现完美版的多数据源备份程序
-
简介:在当今数字化时代,无论是企业还是个人,数据的安全性和业务的连续性都是至关重要的。数据一旦丢失,可能会造成无法估量的损失。因此,如何有效地对分布在不同位置的数据进行备份,尤其是异地备份,成为了一个...
- docker搭建系统环境(docker搭建centos)
-
Docker安装(CentOS7)1.卸载旧版Docker#检查已安装版本yumlistinstalled|grepdocker#卸载旧版本yumremove-ydocker.x...
- 基础篇:数据库 SQL 入门教程(sql数据库入门书籍推荐)
-
SQL介绍什么是SQLSQL指结构化查询语言,是用于访问和处理数据库的标准的计算机语言。它使我们有能力访问数据库,可与多种数据库程序协同工作,如MSAccess、DB2、Informix、M...
- Java21杀手级新特性!3行代码性能翻倍
-
导语某券商系统用这招,交易延迟从12ms降到0.8ms!本文揭秘Oracle官方未公开的Record模式匹配+虚拟线程深度优化+向量API神操作,代码量直降70%!一、Record模式匹配(代码量↓8...
- 一文读懂JDK21的虚拟线程(java虚拟线程)
-
概述JDK21已于2023年9月19日发布,作为Oracle标准Java实现的一个LTS版本发布,发布了15想新特性,其中虚拟线程呼声较高。虚拟线程是JDK21中引入的一项重要特性,它是一种轻量级的...
- 效率!MacOS下超级好用的Linux虚拟工具:Lima
-
对于MacOS用户来说,搭建Linux虚拟环境一直是件让人头疼的事。无论是VirtualBox还是商业的VMware,都显得过于笨重且配置复杂。今天,我们要介绍一个轻巧方便的纯命令行Linux虚拟工具...
- 所谓SaaS(所谓三维目标一般都应包括)
-
2010年前后,一个科技媒体的主编写一些关于云计算的概念性问题,就可以作为头版头条了。那时候的云计算,更多的还停留在一些概念性的问题上。而基于云计算而生的SaaS更是“养在深闺人未识”,一度成为被IT...
- ORA-00600 「25027」 「x」报错(报错0xc0000001)
-
问题现象:在用到LOB大对象的业务中,进行数据的插入,失败了,在报警文件中报错:ORA-00600:内部错误代码,参数:[25027],[10],[0],[],[],[],[],[...
- 安卓7源码编译(安卓源码编译环境lunch失败,uname命令找不到)
-
前面已经下载好源码了,接下来是下载手机对应的二进制驱动执行编译源码命令下载厂商驱动https://developers.google.com/android/drivers?hl=zh-cn搜索NGI...
- 编译安卓源码(编译安卓源码 电脑配置)
-
前面已经下载好源码了,接下来是下载手机对应的二进制驱动执行编译源码命令下载厂商驱动https://developers.google.com/android/drivers?hl=zh-cn搜索NGI...
- 360 Vulcan Team首战告捷 以17.5万美金强势领跑2019“天府杯“
-
2019年11月16日,由360集团、百度、腾讯、阿里巴巴、清华大学与中科院等多家企业和研究机构在成都联合主办了2019“天府杯”国际网络安全大赛暨2019天府国际网络安全高峰论坛。而开幕当日最激荡人...
- Syslog 日志分析与异常检测技巧(syslog发送日志配置)
-
系统日志包含有助于分析网络设备整体运行状况的重要信息。然而,理解并从中提取有效数据往往颇具挑战。本文将详解从基础命令行工具到专业日志管理软件的全流程分析技巧,助你高效挖掘Syslog日志价值。Gr...
- 从Oracle演进看数据库技术的发展(从oracle演进看数据库技术的发展的过程)
-
数据库技术发展本质上是应用需求驱动与基础架构演进的双向奔赴,如何分析其技术发展的脉络和方向?考虑到oracle数据库仍然是这个领域的王者,以其为例,管中窥豹,对其从Oracle8i到23ai版本的核...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- oracle位图索引 (74)
- oracle基目录 (50)
- oracle批量插入数据 (65)
- oracle事务隔离级别 (53)
- oracle主从同步 (55)
- oracle 乐观锁 (51)
- redis 命令 (78)
- php redis (88)
- redis 存储 (66)
- redis 锁 (69)
- 启动 redis (66)
- redis 时间 (56)
- redis 删除 (67)
- redis内存 (57)
- redis并发 (52)
- redis 主从 (69)
- redis 订阅 (51)
- redis 登录 (54)
- redis 面试 (58)
- 阿里 redis (59)
- redis 搭建 (53)
- redis的缓存 (55)
- lua redis (58)
- redis 连接池 (61)
- redis 限流 (51)