-- 查看当前用户语句有 select * from user_sys_privs; --查看当前用户的系统权限 select * from user_role_privs; --查看当前用户被授予的角色 select * from role_sys_privs; --查看角色对应的系统权限
select * from dba_roles; --查看所有角色为dba select * from user_tablespaces; --查看该用户所有的表空间 select * from all_users; --查看所有用户 select * from all_tables; --查看所有用户的表
-- 查询当前用户所有表 select table_name, tablespace_name from tabs; select table_name, tablespace_name from user_tables;
-- 改,修改字段对应的值 (update 表名 set 字段名 = '值') update 表名 set 字段名 = '值'where 字段名 = '值'; -- 无条件则修改该字段所有值
第6节 - 通配符 序列操作 表的备份 别名使用
/* SQL:结构化查询语句 DML:数据操作语言 DDL:数据定义语言 */
/* 通配符 (like %上海% 或者 like 张_) % 百分号:为任意长度,任意内容 _ 下划线:为一个长度,任意内容 一般用作条件,修改或查询其他字段对应值。注意:容易写成=等号 */ select 字段名或* from 表名 where 字段名 like 通配符; update 表名 set 字段名 = '值'where 字段名 like 通配符;
-- Oracle表的备份 createtable 新表名 as select * from 旧表名;
-- Oracle简单查询 (scott自带两张表:emp, dept) select * from 表名; -- 查询表的所有信息 select 字段1, 字段2, ...... from 表名; -- 查询表的部分字段信息 -- 去掉重复内容查询 (多行数据的值在字段内完全一样,则只显示一行值) selectdistinct 字段名, ...... from 表名;
-- Oracle 语法不区分大小写,但字符串内区分! select * from emp where ename = 'jack'; -- 错误写法 select * from EMP whEre Ename = 'JACK'; -- 正确写法
-- 给字段取别名 (无单引号,别名包括含空格时则需要双引号:as 自定义别名) select empno as 编号, deptno as"部门 编号"from emp; -- as 可以省略不写 select 字段名 as 中文注释, 字段名 中文注释 from 表名;
/* ① as可以省略,可写可不写 ② 空格特殊:"中文 中文" from 表名; 一般不用加引号 ③ 取别名不是修改,只是暂时在查询结果中改个显示名字 */
第7节 - 算数操作 字符串拼接 排序 模糊查询 between and用法 in用法
-- 空值null与其他数据操作时结果都会变为null select sal + comm as 总工资 from emp; -- 没有提成的,变null -- 问题:没有提成的职员都会变空值 select sal + nvl(comm, 0) as 总工资 from emp; -- 把空值转为0 -- 解决:在有可能为空的字段前加上nvl(字段名, 替代值)
-- 字符串拼接(|| java中的或者条件符,可以拼接任何类型),还有一种concat方法 select'员工信息:' || empno || ename || sal || ... as 别名 from emp;
-- 排序(order by 字段名; asc为默认升序,可以省略不写,desc为降序,要写) select * from emp orderby sal asc/desc;
-- 多字段排序:(注意:over恰好相反) select * from emp orderby sal desc, empno desc; -- 先按工资降序排序,如有相同值再按部门编号排降序
-- 针对有空值字段排序(Oracle认为空值是最大值) -- 升序asc看不出问题,desc降序问题就出来了。解决方案:nulls last select * from emp orderby comm descnullslast;
-- 模糊查询:like 通配符(%或_) -- 查询姓名以'J'开头的职员信息 select * from emp where ename like'J%'; -- 字符串内区分大小写 -- 查询名字中含有'A'的职员名字 select ename as 姓名 from emp where ename like'%A%'; -- 查询'J'开头,总共4个字母的人 select * from emp where ename like'J____'; -- 4个_通配符
-- 空值查询:查询所有奖金为空/不为空的职员 select * from emp where comm isnull/isnotnull;
-- between and 用法(可用于数字之间也可以用于Date时间之间)区间选值 select * from emp where deptno >= 10and deptno <= 20; -- between 10 and 20 select * from emp where hiredate between'1-1月-1981'and'31-12月-1981';
-- in 用法(or或者,后面复杂查询语句有用到) 绝对是多选一有值 select * from emp where sal = 1000or sal = 2000; select * from emp where sal in(1000, 2000);
-- 显示出emp表中的前8行记录(使用rownum) selectrowid, rownum, e.* from emp e whererownum <= 8;
/* 数据统计:统计某个字段的数据 ① 聚合分组关键字:count、sum、avg、min、max、group by、having ② 其中五个聚合函数为:count(个数) sum(求和) avg(平均值) min(最小值) max(最大值) ③ 聚合分组含义:查询语句中加入了聚合函数,在进行了分组查询。 */
-- count用法:专门用来统计某表中某个字段值的个数 selectcount(ename) from emp; -- 统计单个字段行数 selectcount(*) from emp; -- 统计表的总行数 -- 特殊写法:不重复个数查询:distinct selectcount(distinct job) from emp;
-- sum用法:统计某个(数字)字段中所有数据的总和(忽略空值) selectsum(sal) + sum(comm) as 别名 from emp;
-- avg用法:统计某个(数字)字段中所有数据的平均值(忽略空值) selectavg(sal), avg(comm) from emp;
-- min、max用法:可以用于比较任何类型的字段 selectmax(sal), min(comm) from emp; -- 比较数字 selectmax(hiredate) from emp; -- 比较进入公司时间 selectmin(ename) from emp; -- 比较名字的字母A~Z,中文不行
-- 附带条件查询:查询10部门的平均工资 selectavg(sal) from emp where deptno = 10;
-- sum、avg忽略空值,不是数字时报错:无效数字,而min、max可以用于比较任何类型
第9节 - 聚合分组group by使用 语句写法分解
/* 聚合分组,分组group by的概念: ① 将一个或多个字段的相同值分成一组 ② 取代了一行一行查询繁琐 */ select 字段A, sum(字段), avg(字段) from 表名 groupby 字段A; -- 字段A注意前后呼应
-- 统计每个部门/每个职位的平局工资 select deptno/job, avg(sal) from emp groupby deptno/job;
-- 统计不同职位的人数 select job, count(*) from emp groupby job;
-- 学生成绩信息,显示对应学生姓名 (两张表) select * from studentinfo s join studentexam e on s.stuid = e.estuid;
-- 学生名字,班级编号,带班老师姓名 (三张表) select s.stuname, c.classnumber, t.teachername from studentinfo s join classinfo c on s.sclassid = c.classid join teacherinfo t on c.cteacherid = t.teacherid; -- 步骤:连接表1表2,公共字段写完了,再join表三on公共字段
第15节 - 高级连表查询 连表步骤 外连接 交叉连接
-- 高级连表查询第二种写法 (常用) select 字段,字段,字段 from 表名, 表名, 表名 where 公共字段 and 公共字段; -- 切记:不管要做什么操作,先连接好所用的表!
select s.stuname, c.classnumber, t.teachername from studentinfo s, classinfo c, teacherinfo t where s.sclassid = c.classid and c.cteacherid = t.teacherid;
/* 连表步骤十分重要: ① 先连接 ② 再看需求操作 ③ 再对应修改查询语句 */
-- 实战:where条件中公共字段加入and条件,例如:查询'张三'的考试次数 selectcount(*) from studentinfo s, studentexam e where s.stuid = e.estuid and s.stuname = '张三';
-- 外连接:left right full (只能用join 表名 on 公共字段) -- 含义:以一张表作为主表,主表信息全部显示,从表只显示与主表能搭配的数据 select * from emp e leftjoin dept d on e.depton = d.depton; -- 同理right:右表全部列出,左表只显示匹配数据。(匹配对应公共字段) -- 同理full:两边数据都显示,没有匹配上的公共字段的值为空
-- 交叉连接 cross 一通乱连没有on公共字段 select * from emp e crossjoin dept t;
-- 查询成绩大于80分的学员姓名和考试科目 select s.stuname, e.examsubject, e.examresult from studentinfo s join studentexam e on s.stuid = e.estuid where e.examresult >= 80; -- 第二种写法 select s.stuname, e.examsubject, e.examresult from studentinfo s, studentexam e where s.stuid = e.estuid and e.examresult >= 80;
-- 代码规范问题,第一:分步写。第二:注释写上
第16节 - 简单子查询 嵌套查询 in的用法
-- 简单子查询 也叫嵌套查询,以一张表查出结果作为条件 /* 子查询详解: ① 只有一张表,条件嵌套其他表 ② 大查询(小查询) ③ 小查询作为条件融入大查询 变相理解:类似java中,定义其变量,得到返回值后,再作为条件变量参数 */
-- 语法公式:(注意:公共字段=子查询返回值应为公共字段) select * from 表1 where 表1某字段 = (select 表2与表1公共字段 from 表2 where 表2字段 = (条件));
-- 查询emp表中所有ACCOUNTING部门的职员 select * from emp where deptno = (select deptno from dept where dname = 'ACCOUNTING');
-- 查询出'李四'带的班级信息 select * from classinfo where cteacherid = (select teacherid from teacherinfo where teachername = '李四'); -- 由此看出:表1 where 字段 = (表2查询结果返回值一定要为表1字段);
-- 查询所有高于平均工资的职员信息 select * from emp where sal > (selectavg(sal) from emp);
-- 难点:in的用法晋级 比较操作符的子查询查询出的结果必须只有一个值 -- 查询所有地址在NEW YORK与DALLAS的部门职员 select * from emp where deptno in-- 此处必须要用in,因为查询出的结果肯定不止一个 (select deptno from dept where loc in('NEW YORK', 'DALLAS')); -- in用法深入:一个字段可以在多个值之间任取,多个值一定是一列(一个字段中)中多个行
-- 查询出所有参加Java考试的学生 select * from studentinfo where stuid in-- 此处用in更保险,即使一个值也可以用in (select estuid from studentexam where examsubject = 'Java');
-- 用连接查询显示没有考试的学生 select * from studentinfo s fulljoin studentexam e on s.stuid = e.estuid where e.examid isnull; -- 不为空则为:is not null
-- 查询所有与'SMITH'同部门同职位的职员 select * from emp where job = (select job from emp where ename = 'SMITH') and deptno = (select deptno from emp where ename = 'SMITH');
-- 第二种写法 select * from emp where (job, deptno) in-- 注意:如果是不同部门则需要分开写 (select job, deptno from emp where ename = 'SMITH');
-- 需要注意的是:使用连接查询作为子查询时,要去掉重复字段即公共字段 select * from (select e.*, d.dname, d.loc from emp e, dept d where e.deptno = d.deptno) Y;
/* 查询结果暂存TEMP ① 放from后面,而不是放where后面 ② 表1后面加上逗号,因为后面也是新表 ③ 连接查询时,去掉重复字段只留一个,因为表中不能有重复字段名 所以e.*所有emp字段,包括deptno。而d.dname, d.loc就不能再写d.deptno */
-- 查询职员信息以及所在部门的平均工资 select * from emp e, (select deptno, avg(sal) from emp groupby deptno) Y where e.deptno = Y.deptno;
-- 查询工资高于每个部门平均工资的人 select * from emp e, (select deptno, avg(sal) as avgsal from emp groupby deptno) Y where e.deptno = Y.deptno -- 原表与新表挂钩 and e.sal > Y.avgsal; -- 新表新字段avgsal与原表sal比较
/* 仔细辨别别名 ① 原表别名 ② 字段别名 ③ 新表别名 */
第18节 - 高级查询难题解析 伪列妙用 分页查询
-- 命题:显示学员信息,以及所在班级的平均分
/* 分析: ① 查询班级编号 ② 查询班级的平均分 (与①作为新表) ③ 将上面的结果与学生信息表连接 */
-- 写法原型 select * from studentinfo s, studentexam e, classinfo c where s.stuid = e.estuid and s.sclassid = c.classid; -- ② 修改平均分:把*换成 avg(examresult) as avge 所有班级考试总平均分 -- ③ 分组,语句末尾加上 group by c.classid,对应平均分之前加入c.classid, -- ④ 大括号全部括起来,当做新表,并取名Y -- ⑤ 大查询 select * from studentinfo s, (新表) Y -- ⑥ 末尾加上条件 where s.sclassid = Y.classid 公共字段,连表
select * from studentinfo s (select c.classid, avg(examresult) as avge from studentinfo s, studentexam e, classinfo c where s.stuid = e.estuid and s.sclassid = c.classid groupby c.classid) Y where s.sclassid = Y.classid;
-- 查询工资最低5人,使用伪列rownum与排序 selectrownum, Y.* from (select * from emp orderby sal) Y whererownum > 5; -- 关键:排序原表order,得到新表,在用rownum排序新表 -- 避免order by与rownum冲突,有点像偷梁换柱
-- Oracle分页查询经常要用到 -- 原理:将伪列转换成临时表的一个普通列(字段) select * from (selectrownum RN, e.* from emp e) Y where Y.RN > 1and Y.RN <= 5; /* 一页只显示5行数据 伪列不能大于等于,好比没有1,2,3...就没有5,不能凭空出现 所以只能再次偷梁换柱,将伪列变成新表中的一个字段 最后,再将该字段写条件,这样就可以写大于和指定的5 Y.RN 实质上是不存在的 */
最后给大家上一段:标准的连接Oracle数据库的示例Java代码
publicvoidtestOracle(){ Connection con = null; // 创建一个数据库连接 PreparedStatement pre = null; // 创建预编译语句对象,一般都是用这个而不用Statement ResultSet result = null; // 创建一个结果集对象 try { Class.forName("oracle.jdbc.driver.OracleDriver"); // 加载Oracle驱动程序 System.out.println("开始尝试连接数据库!"); // 127.0.0.1是本机地址,DBname是精简版Oracle的默认数据库名 String url = "jdbc:oracle:" + "thin:@127.0.0.1:1521:DBname"; String user = "simon"; // 用户名,系统默认的账户名 String password = "123456"; // 你安装时选设置的密码 con = DriverManager.getConnection(url, user, password); // 获取连接 System.out.println("连接成功!"); String sql = "select * from student where name=?"; // 预编译语句,“?”占位符代表参数 pre = con.prepareStatement(sql); // 实例化预编译语句 pre.setString(1, "西门提督"); // 设置参数,前面的1表示参数的索引,而不是表中列名的索引 result = pre.executeQuery(); // 执行查询,注意括号中不需要再加参数 while (result.next()) // 当结果集不为空时 System.out.println("学号:" + result.getInt("id") + "姓名:" + result.getString("name")); } catch (Exception e) { e.printStackTrace(); } finally { try { // 逐一将上面的几个对象关闭,因为不关闭的话会影响性能、并且占用资源 // 注意关闭的顺序,最后使用的最先关闭 if (result != null) result.close(); if (pre != null) pre.close(); if (con != null) con.close(); System.out.println("数据库连接已关闭!"); } catch (Exception e) { e.printStackTrace(); } } }