1. --sql structured query language
  2.  
  3. --DML--Data Manipulation Language--数据操作语言
  4.  
  5. query information (SELECT),
  6. add new rows (INSERT),
  7. modify existing rows (UPDATE),
  8. delete existing rows (DELETE),
  9. perform a conditional update or insert operation (MERGE),
  10. see an execution plan of SQL (EXPLAIN PLAN),
  11. and lock a table to restrict access (LOCK TABLE).
  12.  
  13. --DDL--Data Definition Language--数据定义语言
  14. create, modify,drop, or rename objects (CREATE,ALTER,DROP,RENAME),
  15. remove all rows from a database object without dropping the structure (TRUNCATE),
  16. manage access privileges (GRANT,REVOKE),
  17. audit database use (AUDIT,NOAUDIT)
  18. and add a description about an object to the dictionary (COMMENT).
  19.  
  20. --Transaction Control事务控制语句
  21. save the changes(COMMIT)
  22. or discard the changes (ROLLBACK) made by DML statements.
  23. Also included in the transaction-control statements are statements to set a point or marker in the transaction for possible rollback (SAVEPOINT)
  24. and to define the properties for the transaction (SET TRANSACTION).
  25. Used to manage the properties of the database.
  26. There isonly one statement in this category (ALTER SYSTEM).
  27.  
  28. --DCL--Data Contro Language--与开发关系不是很密切,用于权限的分配与回收
  29. grant,revoke,data control
  30.  
  31. --Session Control
  32. control the session properties (ALTER SESSION)
  33. and to enable/disable roles (SET ROLE).
  34.  
  35. --System Control
  36.  
  37. --------------------------------------------------------
  38. select的用法
  39.  
  40. --每个员工的所有信息
  41. select * from emp;
  42. --每个人的部门编号,姓名,薪水
  43. select empno, ename, sal from emp;
  44. --每个人的年薪
  45. select ename, sal*12 from emp;
  46. --计算2*3的值
  47. select 2*3 from emp;
  48. --计算2*3的值(dual)
  49. select 2*3 from dual;
  50. --得到当前时间
  51. select sysdate from dual;
  52. --可以给列起别名,比如求每个人的年薪
  53. select ename, sal*12 annual_sal from emp;
  54. --如果别名中有空格,需要用双引号
  55. select ename, sal*12 "annual sal" from emp;
  56. --如果没有内容,则为空
  57. select ename, sal, comm from emp; /*null*/
  58. --当空字段参与计算,则结果是null
  59. --例如:计算每个人的全年的收入包括月薪和年终奖
  60. select ename, sal * 12 + comm from emp;
  61. --可以将多个字符串拼在一起。比如:求每个人的薪水,格式为smith-sal-123
  62. select ename || '-' || sal || '-' || comm from emp;
  63. --如果字符串中有单引号,需要用另外一个单引号转义,比如:这样一个字符串: he's friend
  64. select ename || 'he''s friend' from emp;
  65.  
  66. --------------------------------------------------------
  67. --distinct 关键词的用法
  68. --求有哪些个部门
  69. select deptno from emp;
  70. select distinct deptno from emp;
  71. --可以用来修饰多个字段
  72. --求有哪些个部门和job的组合
  73. select deptno , job from emp;
  74. select distinct deptno , job from emp;
  75.  
  76. --------------------------------------------------------
  77. where关键词的用法
  78. --可以是数值类型的等值判断。比如:求10这个部门的所有员工
  79. select * from emp where deptno = 10;
  80. --可以是字符串类型的等值判断。比如:求叫KING的这个人的信息
  81. select * from emp where ename = 'KING';
  82. --也可以是不等值判断。比如:求薪水小于2000的员工信息
  83. select * from emp where sal > 2000;
  84. --字符串也可以做不等值判断,比如:求所有ename大于'CBA'的员工信息。
  85. select ename from emp where ename > 'CBA';
  86. --求部门不是10的部门
  87. select * from emp where deptno <> 10;
  88. --求薪水在800和1500之间的员工信息
  89. select * from emp where sal between 800 and 1500;
  90. --也可以写成
  91. select * from emp where sal >= 800 and sal <= 1500;
  92.  
  93. /*这样写则不可以
  94. --select * from emp where 800 <= sal <= 1500;
  95. */
  96. --where...in..的用法。比如:求薪水是800或者1500或正2000的员工信息
  97. select ename, empno, sal from emp where sal in (800, 1500, 2000);
  98. --相当于写成这样
  99. select ename, empno , sal from emp where sal = 800 or sal = 1500 or sal = 2000;
  100. --再比如求姓名是KING,SMITH,AA的员工信息
  101. select ename, empno , sal from emp where ename in ('KING', 'SMITH', 'AA');
  102. --求入职时间在20-2月-81之后的员工信息
  103. select ename, hiredate from emp where hiredate > '20-2月-81';
  104.  
  105. --------------------------------------------------------
  106. --and or not的用法
  107. --求薪水大于1000或者部门在10这个部门的员工信息
  108. select * from emp where sal > 1000 or deptno = 10;
  109. --求薪水不是800或者不是1500或者不是3000的员工信息
  110. select * from emp where sal <> 800 and sal <> 1500 and sal <> 3000;
  111. --也可以这样来写
  112. select * from emp where sal not in (800, 1500, 3000);
  113.  
  114. --------------------------------------------------------
  115. --like的用法
  116. --求名字中包含ALL这三个字符的员工信息
  117. select ename from emp where ename like '%ALL%';
  118. --求名字中的第二个字母是A的员工
  119. select ename from emp where ename like '_A%';
  120. --特殊字符需要转义。比如:求员工中包含特殊字符%的员工信息
  121. select ename from emp where ename like '%\%%' escape '\';
  122.  
  123. --------------------------------------------------------
  124. --null的用法
  125. --求没有年终奖的员工
  126. select ename from emp where comm is null;
  127. --求有年终奖的员工
  128. select ename from emp where comm is not null;
  129.  
  130. --------------------------------------------------------
  131. --order by的用法
  132. --员工信息按照姓名正序排列
  133. select ename, sal from emp order by ename asc; --ascent
  134. --员工信息按照倒叙排列
  135. select ename, sal from emp order by ename desc; --descent
  136. --也可以是多个字段组合排列。例如:员工信息按照部门正序排列,并且按照姓名倒叙排列
  137. select ename, sal, deptno from emp order by deptno asc, ename desc;
  138.  
  139. --------------------------------------------------------
  140. --function的用法
  141. --把所有姓名变成小写
  142. select lower(ename) from emp;
  143. --把所有姓名变成大写
  144. select upper(ename) from emp;
  145. --求所有人名中包含'a'的员工信息不区分大小写
  146. select ename from emp where lower(ename) like '%a%';
  147. --截取子字符串,比如求Hello的一部分
  148. select substr('Hello', 2) from dual;
  149. --求Hello的一部分,并指明长度
  150. select substr('Hello', 2, 3) from dual;
  151. --求ascii码对应的字符
  152. select chr(65) from dual;
  153. --求字符对应的ascii
  154. select ascii('中') from dual;
  155. --四舍五入
  156. select round(23.652) from dual;
  157. --四舍五入小数点后面多少位
  158. select round(23.652, 1) from dual;
  159. --四舍五入小数点前面多少位
  160. select round(23.652, -1) from dual;
  161.  
  162. --------------------------------------------------------
  163. --important!日期转换函数
  164. --------------------------------------------------------
  165. --将当前日期转换成1981-03-12 12:00:00这种形式的字符串
  166. select to_char(sysdate, 'YYYY-MM-DD HH24:MI:SS') from dual;
  167. --将1981-03-12 12:00:00字符串转换成日期
  168. select to_date('1981-03-12 12:00:00', 'YYYY-MM-DD HH24:MI:SS') from dual;
  169. --将每个人的薪水转换成固定格式的字符串
  170. select to_char(sal, 'L00,000.9999') from emp;
  171. --将固定格式的字符串转换成数值
  172. select to_number('$1,250.00', '$9,999.99') from dual;
  173.  
  174. --nullnull参与计算时候,需要要nvl这个函数
  175. select ename, sal*12+comm from emp;
  176. select ename, sal*12+ nvl(comm, 0) from emp;
  177.  
  178. --------------------------------------------------------
  179. --group function组函数
  180. --求所有人的薪水的总和,平均值,最大值,最小值
  181. select sum(sal) , avg(sal), max(sal) , min(sal) from emp;
  182. --求总的行数
  183. select count(*) from emp;
  184. --求总的行树,(可以指定具体的字段)但如果字段有null值的时候需要小心使用
  185. select count(comm) from emp;
  186. --也可以过滤掉重复的行之后统计行数
  187. select count(distinct deptno) from emp;
  188.  
  189. --可以指明按照哪个字段进行分组.比如;分部门统计最高薪水
  190. select deptno, max(sal) from emp group by deptno;
  191. --也可以按照多个字段来分组统计,比如:分部门和岗位,统计最高薪水和行数
  192. select deptno, job , max(sal), count(*) from emp group by deptno, job;
  193.  
  194. --------------------------------------------------------
  195. --重要:出现在select列表中的字段,如果没有在组函数中,那么必须出现在group by 子句中。
  196. --------------------------------------------------------
  197. --select ename, deptno, max(sal) from emp group by deptno;
  198. --select ename, max(sal) from emp;
  199.  
  200. --求薪水最高的员工姓名
  201. select max(sal) from emp;
  202. select ename, sal from emp where sal = 5000;
  203. select ename from emp where sal = (select max(sal) from emp);
  204.  
  205. --having从句的用法
  206. --求平均薪水是2000以上的部门
  207. select avg(sal), deptno from emp group by deptno having avg(sal) > 2000;
  208.  
  209. --------------------------------------------------------
  210. --总结一下select语法
  211. select
  212. from
  213. where
  214. group by
  215. having
  216. order by
  217. --------------------------------------------------------
  218. -- 执行顺序very important!
  219. -- 首先执行where语句将原有记录过滤;
  220. -- 第二执行group by 进行分组;
  221. -- 第三执行having过滤分组;
  222. -- 然后将select 中的字段值选出来;
  223. -- 最后执行order by 进行排序;
  224.  
  225. --------------------------------------------------------
  226. /*
  227. 按照部门分组统计,求最高薪水,平均薪水
  228. 只有薪水是1200以上的才参与统计
  229. 并且分组结果中只包括平均薪水在1500以上的部门
  230. 而且按照平均薪水倒叙排列
  231. */
  232. select max(sal),avg(sal), deptno
  233. from emp
  234. where sal > 1200
  235. group by deptno
  236. having avg(sal) > 1500
  237. order by avg(sal) desc;
  238. --------------------------------------------------------
  239. /*
  240. 把雇员按部门分组,
  241. 求最高薪水, 部门号,
  242. 过滤掉名字中第二个字母是'A'的,
  243. 要求分组后的平均薪水>1500,
  244. 按照部门编号倒序排列
  245. */
  246. select deptno, max(sal)
  247. from emp
  248. where ename not like '_A%'
  249. group by deptno
  250. having avg(sal) > 1500
  251. order by deptno desc;
  252.  
  253. /* very very important! */
  254. select ename, deptno from emp;
  255. select deptno, dname from dept;
  256.  
  257. ----员工姓名以及员工所在部门的名字同时显示出来
  258. select ename, dname from emp , dept;
  259. select ename, dname from emp , dept where emp.deptno = dept.deptno;
  260.  
  261. --要求每位雇员的薪水等级
  262. select ename, sal, grade from emp, salgrade where emp.sal >= salgrade.losal and emp.sal <= salgrade.hisal;
  263. select ename, sal, grade from emp e, salgrade s where e.sal between s.losal and s.hisal;
  264.  
  265. --求工作职位是’PRESIDENT’的雇员姓名,部门名称和薪水等级时
  266. select ename, dname, grade
  267. from emp e, dept d, salgrade s
  268. where e.deptno = d.deptno and e.sal between s.losal and s.hisal
  269. and job = 'PRESIDENT';
  270.  
  271. --求每位员工的姓名,及其上级经理的姓名
  272. select empno, ename, mgr from emp;
  273. select e1.ename, e2.ename from emp e1, emp e2 where e1.mgr = e2.empno;
  274.  
  275. --新语法
  276. --在SQL1992的语法规则中,语句过滤的条件和表连接的条件都被放在了where子句中,当条件过多时,容易造成混淆,
  277. --SQL1999修正了这个缺点,将连接条件和数据过滤条件区分开来,
  278.  
  279. --交叉连接
  280. --结果会产生这两张表的笛卡尔乘积
  281. select ename , dname from emp cross join dept; --inner join
  282.  
  283. --要用deptno作为等值连接条件,我们可以这样写
  284. select ename, dname from emp join dept using(deptno);
  285. --相当于
  286. select ename, dname from emp join dept on emp.deptno = dept.deptno;
  287. --也可以写成这样
  288. select ename, dname from emp join dept on (emp.deptno = dept..deptno);
  289.  
  290. --也可以用于非等值连接
  291. --求每位雇员的薪水等级
  292. select ename, sal, grade from emp
  293. join salgrade on (emp.sal >= salgrade.losal and emp.sal <= salgrade.hisal);
  294.  
  295. --多个join,where组合使用
  296. --(求工作职位是’PRESIDENT’的雇员姓名,部门名称和薪水等级时)
  297. select ename, dname , grade from emp e
  298. join dept d on (e.deptno = d.deptno)
  299. join salgrade s on (e.sal between s.losal and s.hisal)
  300. where job = 'PRESIDENT';
  301.  
  302. --外连接--取出表中连接不到一起的多余的数据
  303. --没有全内连接,没有右内连接
  304.  
  305. --其中outer也可以省略,简写为left join , right join , full join
  306. --left inner join可以缩写成inner join 也可以缩写成join,意思是左内。
  307. --update emp set deptno=null where ename='SMITH';
  308. --commit;
  309. --左内
  310. select dname,ename from emp left inner join dept using(deptno)
  311. --左外连接
  312. select ename,dname from emp left outer join dept using(deptno)
  313. --右外连接
  314. select ename,dname from emp right outer join dept using(deptno)
  315. --全外连接
  316. select ename,dname from emp full outer join dept using (deptno);
  317. --左外,右外的区别
  318. select e1.ename,e2.ename from emp e1 join emp e2 on(e1.mgr = e2.empno);
  319. select e1.ename,e2.ename from emp e1 left outer join emp e2 on(e1.mgr = e2.empno);
  320. select e1.ename,e2.ename from emp e1 right outer join emp e2 on(e1.mgr = e2.empno);
  321. select e1.ename,e2.ename from emp e1 full outer join emp e2 on(e1.mgr = e2.empno);
  322.  
  323. --什么时候用外连接呢:
  324. ----比如领导向你要所有学生的列表,顺便把所属的班级也列出来,就需要外连接
  325.  
  326. --在Where语句中使用子查询
  327. -----------------------------------------------------------------
  328. --雇员中最高薪水的人员名称
  329. --1,先求出最高薪水
  330. --2,再求雇员中最高薪水的人员名称
  331. select ename from emp where sal = (
  332. select max(sal) from emp
  333. );
  334.  
  335. --有哪些人的薪水是在整个雇员的平均薪水之上的
  336. select empno, ename from emp where sal > (select avg(sal) from emp);
  337.  
  338. -----------------------------------------------------------------
  339. --雇员中哪些人是经理人
  340. --1,首先查询mgr中有哪些号码
  341. --2,再看有哪些人员的号码在此出现
  342. select ename from emp where empno in (
  343. select distinct mgr from emp where mgr is not null
  344. );
  345.  
  346. -----------------------------------------------------------------
  347. --在From子句中使用子查询
  348. ------------------------------------------------------------------
  349.  
  350. --部门平均薪水的等级
  351. --1,首先将每个部门的平均薪水求出来
  352. --2,然后把结果当成一张表,再用这张结果表和salgrade表做连接,以此求得薪水等级
  353. select deptno, avg_sal, grade from
  354. (select deptno, avg(sal) avg_sal from emp group by deptno) t
  355. join salgrade s on (t.avg_sal between s.losal and s.hisal);
  356.  
  357. -----------------------------------------------------------------
  358. --每个部门最高薪水的人员名称
  359. --1,首先将每个部门的最高薪水求出来
  360. --2,然后把结果当成一张表,再用emp和这张结果表做连接,以此求得每个部门最高薪水的人员名称
  361. select ename, sal, emp.deptno from emp join
  362. (select deptno, max(sal) max_sal from emp group by deptno) t
  363. on (emp.sal = t.max_sal and emp.deptno = t.deptno);
  364.  
  365. -----------------------------------------------------------------
  366. --哪些人的薪水在部门的平均薪水之上
  367. --1,首先将每个部门的平均薪水求出来
  368. --2,然后把结果当成一张表,再用emp和这张结果表做连接,以此求得哪些人的薪水在部门的平均薪水之上
  369. select ename, sal from emp join
  370. (select deptno, avg(sal) avg_sal from emp group by deptno) t
  371. on (emp.sal > t.avg_sal and emp.deptno = t.deptno);
  372.  
  373. -----------------------------------------------------------------
  374. --求部门中(所有人的)平均的薪水等级,形式如:
  375. -- deptno avg_grade
  376. -- 10 3.67
  377. -- 20 2.8
  378. -- 30 2.5
  379. --1,先求每个人的薪水等级
  380. --2,再按照部门分组,求平均数
  381. select deptno , avg(grade) from
  382. (select ename, deptno, grade from emp e
  383. join salgrade s on (e.sal between s.losal and s.hisal)
  384. )
  385. group by deptno;
  386.  
  387. ------------------------------------------------------------------------------------------
  388. --使用伪字段:rownum,----------------------
  389. ------------------------------------------------------------------------------------------
  390. --用来标识每条记录的行号,行号从1开始,每次递增1
  391. select ename from emp where rownum <= 5;
  392. --oraclerownum只能使用 < <=, 不能使用 = > >= 等比较操作符,
  393. select ename from emp where rownum > 5;
  394. --当rownumorder by 一起使用时,会首先选出符合rownum条件的记录,然后再排序
  395. --(错误的写法)例如,当我们要求薪水最高的前5个人时,最直接的想法可以这样写:
  396. select ename, sal from emp where rownum <= 5 order by sal desc;
  397. --(正确的写法)可以这样写
  398. select ename, sal
  399. from
  400. (select ename, sal from emp order by sal desc)
  401. where rownum <= 5;
  402.  
  403. --------------------------------------------------------
  404. --不准用组函数(即MAX()),求薪水的最高值(面试题)
  405. --第一种解决办法:
  406. --1,先把所有薪水按照倒序排列
  407. --2,再取第一行
  408. select sal from (
  409. select sal from emp order by sal desc
  410. )
  411. where rownum <= 1;
  412.  
  413. --第二种解决办法:
  414. --1,先跨表查询自己,先求出的结果中,e1.sal不可能出现最大数
  415. --2,然后再not in
  416. select distinct sal from emp where sal not in (
  417. select distinct e1.sal from emp e1 join emp e2 on (e1.sal < e2.sal)
  418. );
  419.  
  420. -----------------------------------------------------------------
  421. --求平均薪水最高的部门的部门编号
  422. --第一种解决办法:
  423. --1,先求出每个部门的平均薪水,
  424. --2,再求每个部门的平均薪水的最高值,
  425. --3,最后再求第一步结果中avg_sal = 最高薪水的记录.
  426. select deptno from
  427. (select deptno, avg(sal) avg_sal from emp group by deptno) t
  428. where avg_sal =
  429. (
  430. select max(avg_sal) from
  431. (select deptno, avg(sal) avg_sal from emp group by deptno)
  432. );
  433.  
  434. --第二种解决办法:
  435. --1,将上面的第一步第二步合并,先求最高平均薪水,用max(avg(sal))的办法
  436. --2,求出每个部门的平均薪水
  437. --3,最后再求第二步结果中(即每个部门的平均薪水),avg_sal = (第一步结果)的记录.即avg_sal =最高薪水的记录.
  438. select deptno from
  439. (select deptno, avg(sal) avg_sal from emp group by deptno) t
  440. where avg_sal = (select max(avg(sal)) from emp group by deptno);
  441.  
  442. --第三种解决办法:
  443. --1,先求出每个部门的平均薪水,
  444. --2,求最高平均薪水,用max(avg(sal))的办法
  445. --3,再使用having语句, avg(sal) = 第二步的结果
  446. 注意:为组函数起的别名在having中不能用
  447. select deptno, avg(sal)
  448. from emp
  449. group by deptno
  450. having avg(sal) = (select max(avg(sal)) from emp group by deptno);
  451.  
  452. -----------------------------------------------------------------
  453. --求平均薪水最高的部门的部门名称
  454. --1,部门平均最高薪水
  455. --2,得到部门编号列表,注意用group by deptno
  456. --3,再应用having子句, having avg(sal) = (第一步的结果)
  457. --4,得到平均最高薪水的那个部门的编号
  458. --5,再得到部门名称
  459.  
  460. select dname from dept where deptno in (
  461. select distinct deptno from emp group by deptno
  462. having avg(sal) = (
  463. select max(avg(sal)) from emp group by deptno
  464. )
  465. )
  466.  
  467. -----------------------------------------------------------------
  468. --求平均薪水的等级最低的部门的部门名称
  469. --第一步:部门平均薪水的等级,分成两个小步骤,第一小步是求部门平均薪水
  470. select deptno, avg_sal, grade from
  471. (select deptno, avg(sal) avg_sal from emp group by deptno) t
  472. join salgrade s
  473. on (t.avg_sal between s.losal and s.hisal)
  474. --第二步:最低的等级值
  475. select min(grade) from (第一步的结果)
  476. --第三步:等于最低值的部门编号
  477. ------------有错误,应该是grade=
  478. select deptno from (第一步的结果) where grade = (第二步的结果)
  479. --第四步:求名称
  480. select dname from dept where deptno in (第三步的结果)
  481.  
  482. select dname from dept where deptno in
  483. (select deptno from
  484. (
  485. select deptno, avg_sal, grade from
  486. (select deptno, avg(sal) avg_sal from emp group by deptno) t
  487. join salgrade s
  488. on (t.avg_sal between s.losal and s.hisal)
  489. )
  490. where grade =
  491. (
  492. select min(grade) from
  493. (
  494. select deptno, avg_sal, grade from
  495. (select deptno, avg(sal) avg_sal from emp group by deptno) t
  496. join salgrade s
  497. on (t.avg_sal between s.losal and s.hisal)
  498. )
  499. )
  500. )
  501.  
  502. --也可以用视图的方式来解决
  503. --conn sys/bjsxt as sysdba
  504. --grant create table, create view, create sequence to scott
  505. --根据第一步的结果,建立一个view
  506. create view v$_dept_info as
  507. select deptno, avg_sal, grade from
  508. (select deptno, avg(sal) avg_sal from emp group by deptno) t
  509. join salgrade s
  510. on (t.avg_sal between s.losal and s.hisal);
  511. --查看一下
  512. desc v$_dept_info;
  513. --查询一下
  514. select * from v$_dept_info;
  515. --带入view
  516. select dname from dept where deptno in (
  517. select deptno from (
  518. v$_dept_info
  519. )
  520. where grade = (
  521. select min(grade) from (
  522. v$_dept_info
  523. )
  524. )
  525. )
  526. -------------------------------------------------------------
  527. --为什么in的后面不能order by
  528. select dname from dept where deptno
  529. in
  530. (select deptno
  531. from salgrade s,( select avg(sal) avg_sal,deptno from emp group by deptno ) t
  532. where t.avg_sal<=s.hisal and t.avg_sal>=s.losal and rownum=1
  533. order by deptno)
  534.  
  535. ---------------------------------------------------------------
  536. --求部门经理人中平均薪水最低的部门名称 (思考题)
  537.  
  538. ----------------------------------------------------------------------------
  539. --求比普通员工的最高薪水还要高的经理人名称
  540. --1,求所有经理的编号
  541. select distinct mgr from emp where mgr is not null
  542. --2,普通员工的最高薪水
  543. select max(sal)
  544. from emp
  545. where empno not in (select distinct mgr from emp where mgr is not null);
  546. --3,
  547. select ename, sal
  548. from emp
  549. where empno in (第一步的结果)
  550. and sal >(第二步的结果)
  551. --即:
  552. select ename, sal
  553. from emp
  554. where empno in (select distinct mgr from emp where mgr is not null)
  555. and sal >
  556. (select max(sal)
  557. from emp
  558. where empno not in
  559. (select distinct mgr from emp where mgr is not null));
  560.  
  561. ------------------------------------------------------------------------------
  562. --求薪水最高的前5名雇员
  563. --1,先观察一下
  564. select rownum , ename , sal from emp;
  565. --2,看看rownum的作用
  566. select rownum ,ename, sal from emp where rownum <= 5;
  567. --3,不是我们想要的结果
  568. select rownum ,ename, sal from emp where rownum <= 5 order by sal desc;
  569. --4,先order by,再rownum
  570. select rownum ,ename, sal from (select ename, sal from emp order by sal desc) where rownum <= 5;
  571.  
  572. --------------------------------------------------------------------------------
  573. --求薪水最高的第6到第10名雇员(重点掌握)
  574. --这种没法实现,oraclerownum只能使用 < <=, 不能使用 = > >= 等比较操作符
  575. --注意里面的rownum和外面的rownum的区别,外面要想访问里面的rownum,必须取得一个别名。
  576. select ename, sal, rownum
  577. from (select ename, sal from emp order by sal desc)
  578. where rownum >= 6 and rownum <= 10;
  579. --所以再套一层select
  580. select ename, sal from
  581. (select ename, sal, rownum r from
  582. (select ename, sal from emp order by sal desc)
  583. )
  584. where r >= 6 and r <= 10;
  585.  
  586. --还有一种排序方式
  587. minus
  588.  
  589. --------------------------------------------------------------------
  590. --练习: 求最后入职的5名员工
  591. --1,每个人的入职时间
  592. select ename, hiredate from emp order by hiredate desc
  593. --2,取前5
  594. select ename, hiredate
  595. from (select ename, hiredate from emp order by hiredate desc)
  596. where rownum <= 5;
  597.  
  598. -----------------------------------------------------------------
  599. --求每个部门中薪水最高的前两名雇员
  600.  
  601. --1,每个员工的工资,按部门和工资排列
  602. select ename, deptno, sal from emp order by deptno, sal desc
  603. --2,套一层,加上个r
  604. select ename, deptno, sal, rownum r
  605. from (select ename, deptno, sal from emp order by deptno, sal desc);
  606. --3,创建试图
  607. create view v$_t as
  608. select ename, deptno, sal, rownum r from (select ename, deptno, sal from emp order by deptno, sal desc);
  609. --观察一下
  610. desc v$_t;
  611. select * from v$_t
  612. --每个部门中,薪水最高的第一行,并创建试图
  613. create view v$_t2 as
  614. select deptno, min(r) min_r from v$_t group by deptno;
  615. select * from v$_t2
  616. --两个view跨表连接,大于薪水最高的行数,小于最高的行数+1,并且部门编号要匹配
  617. select ename, sal from v$_t join v$_t2
  618. on (v$_t.r >= v$_t2.min_r and v$_t.r <= v$_t2.min_r + 1 and v$_t.deptno = v$_t2.deptno);
  619.  
  620. -------------------------------------------------------------------------------
  621. --面试题: 比较效率
  622. select * from emp where deptno = 10 and ename like '%A%';
  623. select * from emp where ename like '%A%' and deptno = 10;
  624.  
  625. ---------------------------------------------------------
  626. --使用unionminus
  627.  
  628. --使用unionminus可以用来实现结果集的合并和去除(可以理解为加和减),例如:
  629. select ename, empno from emp where deptno = 10
  630. union
  631. select ename, empno from emp where deptno = 20
  632. --相当于
  633. select ename, empno from emp where deptno = 10 or deptno = 20;
  634.  
  635. --而下面的语句
  636. select ename, empno from emp where deptno in (10,20)
  637. minus
  638. select ename, empno from emp where sal < 1500
  639. --相当于
  640. select ename, empno from emp where deptno in (10,20) and sal >= 1500;
  641.  
  642. --求分段显示薪水的个数
  643.  
  644. select ename, sal from emp where deptno = 10
  645. union
  646. select ename, sal from emp where sal > 2000;
  647.  
  648. select ename, sal from emp where deptno = 10
  649. minus
  650. select ename, sal from emp where sal > 2000;
  651.  
  652. 如:
  653. scale total
  654. <800 0
  655. 801-1000 2
  656. 1001-2000 3
  657. 2001-5000 6
  658. >5000 8
  659.  
  660. select '<800' as scale , count(*) as total from emp where sal < 800
  661. union
  662. select '801-1000' as scale, count(*) as total from emp where sal between 801 and 1000;
  663.  
  664. --或者显示成为
  665. --注意:使用between .. and .. 的时候,包含了最大和最小值。
  666. 800-1000 1001-2000 2000-5000
  667. 2 3 6
  668. select * from
  669. (select count(*) as "800-1000" from emp where sal between 800 and 1000),
  670. (select count(*) as "1001-2000" from emp where sal between 1001 and 2000),
  671. (select count(*) as "2001-5000" from emp where sal between 2001 and 5000);
  672.  
  673. --或显示成为
  674. DEPTNO 800-2000 2001-5000
  675. ------ ---------- ----------
  676. 30 5 1
  677. 20 2 3
  678. 10 1 2
  679.  
  680. select t1.deptno, "800-2000", "2001-5000" from
  681. (
  682. select deptno , count(*) as "800-2000" from emp where sal between 800 and 2000
  683. group by deptno
  684. ) t1
  685. join
  686. (
  687. select deptno , count(*) as "2001-5000" from emp where sal between 2001 and 5000
  688. group by deptno
  689. ) t2
  690. on
  691. t1.deptno = t2.deptno
  692.  
  693. -----------------------------------------------------------------------------------
  694. --每个薪水等级有多少名雇员
  695. --1,先求出每个雇员的薪水等级
  696. select ename, sal, grade from emp e join salgrade s on (e.sal between s.losal and s.hisal)
  697. --2,再group一下
  698. select grade, count(*)
  699. from (select ename, sal, grade
  700. from emp e
  701. join salgrade s on (e.sal between s.losal and s.hisal))
  702. group by grade;
  703.  
  704. -------------------------------------------------------------------------
  705. 3个表SCSC
  706. SSNOSNAME)代表(学号,姓名)
  707. CCNOCNAMECTEACHER)代表(课号,课名,教师)
  708. SCSNOCNOSCGRADE)代表(学号,课号成绩)
  709. 问题:
  710. 1,找出没选过“黎明”老师的所有学生姓名。
  711. 2,列出2门以上(含2门)不及格学生姓名及平均成绩。
  712. 3,即学过1号课程又学过2号课所有学生的姓名。
  713. 请用标准SQL语言写出答案,方言也行(请说明是使用什么方言)。
  714. -----------------------------------------------------------------------------
  715. CREATE TABLE SC
  716. (
  717. SNO VARCHAR2(200 BYTE),
  718. CNO VARCHAR2(200 BYTE),
  719. SCGRADE VARCHAR2(200 BYTE)
  720. );
  721.  
  722. CREATE TABLE S
  723. (
  724. SNO VARCHAR2(200 BYTE),
  725. SNAME VARCHAR2(200 BYTE)
  726. );
  727.  
  728. CREATE TABLE C
  729. (
  730. CNO VARCHAR2(200 BYTE),
  731. CNAME VARCHAR2(200 BYTE),
  732. CTEACHER VARCHAR2(200 BYTE)
  733. );
  734.  
  735. INSERT INTO C ( CNO, CNAME, CTEACHER ) VALUES ( '', '语文', '张');
  736. INSERT INTO C ( CNO, CNAME, CTEACHER ) VALUES ( '', '政治', '王');
  737. INSERT INTO C ( CNO, CNAME, CTEACHER ) VALUES ( '', '英语', '李');
  738. INSERT INTO C ( CNO, CNAME, CTEACHER ) VALUES ( '', '数学', '赵');
  739. INSERT INTO C ( CNO, CNAME, CTEACHER ) VALUES ( '', '物理', '黎明');
  740. commit;
  741.  
  742. INSERT INTO S ( SNO, SNAME ) VALUES ( '', '学生1');
  743. INSERT INTO S ( SNO, SNAME ) VALUES ( '', '学生2');
  744. INSERT INTO S ( SNO, SNAME ) VALUES ( '', '学生3');
  745. INSERT INTO S ( SNO, SNAME ) VALUES ( '', '学生4');
  746. commit;
  747.  
  748. INSERT INTO SC ( SNO, CNO, SCGRADE ) VALUES ( '', '', '');
  749. INSERT INTO SC ( SNO, CNO, SCGRADE ) VALUES ( '', '', '');
  750. INSERT INTO SC ( SNO, CNO, SCGRADE ) VALUES ( '', '', '');
  751. INSERT INTO SC ( SNO, CNO, SCGRADE ) VALUES ( '', '', '');
  752. INSERT INTO SC ( SNO, CNO, SCGRADE ) VALUES ( '', '', '');
  753. INSERT INTO SC ( SNO, CNO, SCGRADE ) VALUES ( '', '', '');
  754. INSERT INTO SC ( SNO, CNO, SCGRADE ) VALUES ( '', '', '');
  755. INSERT INTO SC ( SNO, CNO, SCGRADE ) VALUES ( '', '', '');
  756. INSERT INTO SC ( SNO, CNO, SCGRADE ) VALUES ( '', '', '');
  757. INSERT INTO SC ( SNO, CNO, SCGRADE ) VALUES ( '', '', '');
  758. INSERT INTO SC ( SNO, CNO, SCGRADE ) VALUES ( '', '', '');
  759. INSERT INTO SC ( SNO, CNO, SCGRADE ) VALUES ( '', '', '');
  760. commit;
  761. ------------------------------------------------------------------------
  762. 答案:
  763. 问题1.找出没选过“黎明”老师的所有学生姓名。
  764. 第一步:求黎明老师教的所有课的课号
  765. select distinct cno from c where cteacher='黎明'
  766. 第二步:选了黎明老师的所有学生的编号
  767. select sno from sc where cno in (
  768. 第一步的结果
  769. )
  770. 第三步:没有选黎明老师的所有学生的姓名
  771. select sname from s where sno not in (
  772. 第二步的结果
  773. )
  774. 即:
  775. select sname from s where sno not in (
  776. select sno from sc where cno in (
  777. select distinct cno from c where cteacher='黎明'
  778. )
  779. )
  780. ----------------------------------------------------------------------------
  781. 问题2:列出2门以上(含2门)不及格学生姓名及平均成绩。
  782. 第一步:2门以上不及格的学生的学号
  783. select sno from sc where scgrade < 60 group by sno having count(*) >= 2
  784. 第二步:每个学生平均分
  785. select sno, avg(scgrade) as avg_grade from sc group by sno
  786. 第三步:第一步中得到的学号对应的学生姓名以及平均分
  787. select s.sname ,avg_grade from s
  788. join
  789. 第一步的结果
  790. on s.sno = t.sno
  791. join
  792. 第二步的结果
  793. on s.sno = t1.sno
  794. 即:
  795. select s.sname ,avg_grade from s
  796. join
  797. (select sno, count(*) from sc where scgrade < 60 group by sno having count(*) >= 2)t
  798. on s.sno = t.sno
  799. join
  800. (select sno, avg(scgrade) as avg_grade from sc group by sno )t1
  801. on s.sno = t1.sno
  802.  
  803. 错误的写法:
  804. 错误在于:求的是所有不及格的课程的平均分,而不是所有课程(包括及格的)的平均分
  805. 执行顺序:
  806. 首先会执行Where语句,将不符合选择条件的记录过滤掉,
  807. 然后再将过滤后的数据按照group by子句中的字段进行分组,
  808. 接着使用having子句过滤掉不符合条件的分组,
  809. 然后再将剩下的数据排序显示。
  810. select sname, avg_scgrade from s join
  811. (select sno, avg(scgrade) avg_scgrade from sc where scgrade < 60 group by sno having count(*) >= 2) t
  812. on (s.sno = t.sno);
  813.  
  814. ----------------------------------------------------------------------------
  815. 问题3:即学过1号课程又学过2号课所有学生的姓名。
  816. 第一步:学过1号课程的学号
  817. select sno from sc where cno = 1
  818. 第二步:学过2号课程的学号
  819. select sno from sc where cno = 2
  820. 第三步:即学过1号课程又学过2号课的学号
  821. select sno from sc where cno =1 and sno in (select sno from sc where cno = 2)
  822. 第四步:得到姓名
  823. select sname from s where sno in (
  824. select sno from sc where cno = 1 and sno in (select sno from sc where cno = 2)
  825. )
  826. 或者:
  827. select sname from s where
  828. sno in (select sno from sc where cno = 1)
  829. and
  830. sno in (select sno from sc where cno = 2)
  831.  
  832. --DML语句
  833. --DML语句用于添加、删除和修改表中的数据,
  834. --包含三条最常用的语句,即InsertUpdateDelete
  835.  
  836. --Insert语句插入数据
  837. --方式一:指定字段列表
  838. insert into emp (empno, ename, job, deptno)
  839. values (9998, 'TEST', 'CLERK', 20);
  840. select * from emp;
  841. --显式的插入一个空值,可以用NULL值来表示,
  842. insert into emp (empno, ename, job, sal , deptno)
  843. values (9997, 'TEST2', 'CLERK', null, 20);
  844. --省略字段列表
  845. insert into emp
  846. values (9999, 'TEST3', 'CLERK', '', NULL, 8000, NULL, 30);
  847. --应用子查询
  848. --可以先查看一下,当前有几个表
  849. select table_name from user_tables
  850. --创建一个表
  851. create table emp7 as select * from emp;
  852. --查询一下
  853. select * from emp7
  854. --再插入一些结果
  855. insert into emp7 (select * from emp5)
  856. --再查询一下,应该28条记录才对
  857. select * from emp5
  858.  
  859. --------------------------------------------------------------------------------------
  860. --Update语句更新数据
  861. update emp
  862. set sal = sal * 1.1;
  863. --修改表中部分的值
  864. --将部门号为10的所有员工的薪水都上涨10%
  865. update emp
  866. set sal = sal * 1.1
  867. where deptno = 10;
  868. --更新多个字段
  869. update emp5
  870. set sal=sal*1.1,ename='aaa'
  871. --应用子查询
  872. --给所有经理涨工资
  873. update emp7 set sal=sal*1.1
  874. where empno in(
  875. select distinct mgr from emp7 where mgr is not null
  876. )
  877.  
  878. ----------------------------------------------------------------------------------
  879. --Delete语句删除数据
  880. --不指定where条件的时候,Delete语句将删除表中全部的数据
  881. select * from emp7;
  882. Delete from emp7;
  883. --删除表中部分数据
  884. Delete from emp2
  885. Where deptno = 20;
  886. --恢复旧有的数据
  887. --(扣钱、吐钱应该作为一组动作同时完成)
  888. --要么同时完成,要么同时不完成的动作就称为一个Transaction
  889. --大多数数据库系统都支持Transaction,在Oracle中,一个Transaction起始于一条DML语句,结束于以下的几种情况:
  890. --1. 用户显式执行Commit语句提交操作或Rollback语句回退。
  891. --2. 当执行DDL语句或DCL语句时事务自动提交。
  892. --3. 用户正常断开连接时,Transaction自动提交。
  893. --4. 系统崩溃或断电时事务自动回退。
  894. delete from emp where empno = 9998;
  895. select * from emp;
  896. commit;
  897. rollback;
  898.  
  899. NUMBER[(precision [, scale])]
  900. NUMBER(p, s)
  901.  
  902. 其中ps都是可选的:
  903. p代表精度,默认为38
  904. s代表小数位数,取值范围-84~127
  905. 默认取值要看是否指定了p
  906. 如果指定了p,默认s0
  907. 如果没有指定p,默认取最大值。
  908.  
  909. 其他的数值类型都是number的衍生,底层都是number,比如integer/int完全映射到number(38)
  910. 默认应该是
  911. number(38,127)
  912.  
  913. 范围: 1 <= p <=38, -84 <= s <= 127
  914. 保存数据范围:-1.0e-130 <= number value < 1.0e+126
  915. 保存在机器内部的范围: 1 ~ 22 bytes
  916. 有效位:从左边第一个不为0的数算起的位数。
  917. s的情况:
  918. s > 0
  919. 精确到小数点右边s位,并四舍五入。然后检验有效位是否 <= p
  920. s < 0
  921. 精确到小数点左边s位,并四舍五入。然后检验有效位是否 <= p + |s|。
  922. s = 0
  923. 此时NUMBER表示整数。
  924.  
  925. eg:
  926. Actual Data Specified As Stored As
  927. ----------------------------------------
  928. 123.89 NUMBER 123.89
  929. 123.89 NUMBER(3) 124
  930. 123.89 NUMBER(6,2) 123.89
  931. 123.89 NUMBER(6,1) 123.9
  932. 123.89 NUMBER(4,2) exceeds precision (有效位为5, 5 > 4)
  933. 123.89 NUMBER(6,-2) 100
  934. .01234 NUMBER(4,5) .01234 (有效位为4)
  935. .00012 NUMBER(4,5) .00012
  936. .000127 NUMBER(4,5) .00013
  937. .0000012 NUMBER(2,7) .0000012
  938. .00000123 NUMBER(2,7) .0000012
  939. 1.2e-4 NUMBER(2,5) 0.00012
  940. 1.2e-5 NUMBER(2,5) 0.00001
  941. 123.2564 NUMBER 123.2564
  942. 1234.9876 NUMBER(6,2) 1234.99
  943. 12345.12345 NUMBER(6,2) Error (有效位为5+2 > 6)
  944. 1234.9876 NUMBER(6) 1235 (s没有表示s=0)
  945. 12345.345 NUMBER(5,-2) 12300
  946. 1234567 NUMBER(5,-2) 1234600
  947. 12345678 NUMBER(5,-2) Error (有效位为8 > 7)
  948. 123456789 NUMBER(5,-4) 123460000
  949. 1234567890 NUMBER(5,-4) Error (有效位为10 > 9)
  950. 12345.58 NUMBER(*, 1) 12345.6
  951. 0.1 NUMBER(4,5) Error (0.10000, 有效位为5 > 4)
  952. 0.01234567 NUMBER(4,5) 0.01235
  953. 0.09999 NUMBER(4,5) 0.09999
  954.  
  955. --delete from test;
  956. --drop table test;
  957. --create table test(
  958. -- n NUMBER
  959. --);
  960. --insert into test (n) values(123.89);
  961.  
  962. --select * from test
  963.  
  964. --第三章 数据库常用对象
  965.  
  966. 字段类型 中文说明 限制条件 其它说明
  967. CHAR 固定长度字符串 最大长度2000 bytes
  968. --VARCHAR2 可变长度的字符串 最大长度4000 bytes 可做索引的最大长度749
  969. NCHAR 根据字符集而定的固定长度字符串 最大长度2000 bytes
  970. NVARCHAR2 根据字符集而定的可变长度字符串 最大长度4000 bytes
  971. --DATE 日期(日-月-年) DD-MM-YYHH-MI-SS 经过严格测试,无千虫问题
  972. LONG 超长字符串 最大长度2G231-1 足够存储大部头著作
  973. RAW 固定长度的二进制数据 最大长度2000 bytes 可存放多媒体图象声音等
  974. LONG RAW 可变长度的二进制数据 最大长度2G 同上
  975. BLOB 二进制数据 最大长度4G
  976. --CLOB 字符数据 最大长度4G
  977. NCLOB 根据字符集而定的字符数据 最大长度4G
  978. BFILE 存放在数据库外的二进制数据 最大长度4G
  979. ROWID 数据表中记录的唯一行号 10 bytes ********.****.****格式,*为01
  980. NROWID 二进制数据表中记录的唯一行号 最大长度4000 bytes
  981. --NUMBER(P,S) 数字类型 P为整数位,S为小数位
  982. DECIMAL(P,S) 数字类型 P为整数位,S为小数位
  983. INTEGER 整数类型 小的整数
  984. FLOAT 浮点数类型 NUMBER(38),双精度
  985. REAL 实数类型 NUMBER(63),精度更高
  986.  
  987. -------------------------------------------------------------------------------------------------------
  988. Category Datatypes
  989. Character CHAR, NCHAR, VARCHAR2, NVARCHAR2
  990. Number NUMBER
  991. Long and raw LONG, LONG RAW, RAW
  992. Date and time DATE, TIMESTAMP, TIMESTAMP WITH TIME ZONE,TIMESTAMP WITH LOCAL TIME ZONE, INTERVAL YEAR TO MONTH, INTERVAL DAY TO SECOND
  993. Large object CLOB, NCLOB, BCLOB, BFILE
  994. Row ID ROWID, UROWID
  995.  
  996. ------------------------------------------------------------------------------------------------------------
  997. --Varchar2(n) 变长字符串,存储空间等于实际空间的数据大小,最大为4K
  998. --Char(n) 定长字符串,存储空间大小固定
  999. --Number(p,s) 整数或小数
  1000. ----ps参数的含义
  1001. --Date 年、月、日、时、分、秒
  1002. --Long 变长字符串,最大字节数达到2GB
  1003. --Oracle还提供了二进制和字节大对象,即BLOBCLOB等类型,常用于二进制数据的保存,例如图片、音频、视频等等,
  1004. --BLOB
  1005. --CLOB
  1006. ---------------------------------------------------------------------------------------------------------------
  1007. --varchar & varchar2 & nvarchar & nvarchar2区别
  1008. 1,varchar早就建议不使用了,应该用VARCHAR2nvarchar估计也不使用的,也应该是使用nvarchar2
  1009. 2,VARCHAR2(size),可变长度的字符串,其最大长度为 size 个字节。
  1010. size 的最大值是 4000,而最小值是 1。您必须指定一个 VARCHAR2 size
  1011. 3,NVARCHAR2(size),可变长度的字符串,依据所选的国家字符集,其最大长度为 size 个字符或字节。
  1012. size 的最大值取决于存储每个字符所需要的字节数,其上限为 4000 个字节。
  1013. 您必须为 NVARCHAR2 指定一个 size
  1014. 4,VARCHAR2NVARCHAR2的不同之处在于它们存放信息占用的空间不同。
  1015. VARCHAR2存放的英文字符只占一个字节,而nvarchar2依据所选的字符集,大多为两个。
  1016. 5,当你的数据库字符集不是unicode,比如ZHS16GBK,
  1017. 但又想在个别字段存储诸如中文冷僻字的unicode字符时,
  1018. 就可以选择nvarchar2,但必须9i版本以上的.
  1019. 6,nvachar定义的是字符数,varchar定义的是字节数
  1020. 所以nvachar(10)放入varchar(10)就会出现此错误,因为varchar(10)只能放10个字节的数据
  1021.  
  1022. select lengthb('錒') from dual;
  1023. -------------------------------------------------------------------------------------------------------------------
  1024. 3.1.1创建表
  1025. --建立一张用来存储学生信息的表,
  1026. drop table stu;
  1027. select * from stu;
  1028. rollback;
  1029. create table stu(
  1030. id number(6),
  1031. name varchar2(20),
  1032. sex number(1),
  1033. age number(3),
  1034. sdate date,
  1035. grade number(2) default 1,
  1036. class number(4),
  1037. email varchar2(50)
  1038. );
  1039. --在创建表的时候,我们还可以使用子查询来参考现有的一张表
  1040. create table emp2
  1041. as
  1042. select * from emp;
  1043. --在子查询中使用任何查询的语法
  1044. create table emp_dept
  1045. as
  1046. select ename, dname from emp join dept using (deptno);
  1047.  
  1048. --创建表时指定约束条件
  1049. --1. NOT NULL 非空
  1050. --2. UNIQUE KEY 唯一
  1051. --3. PRIMARY KEY 主键
  1052. --4. FOREIGN KEY 外键
  1053. --5. CHECK 自定义检查约束
  1054.  
  1055. --非空约束
  1056. 要求姓名不能为空
  1057. create table stu(
  1058. id number(6),
  1059. name varchar2(20) not null,
  1060. sex number(1),
  1061. age number(3),
  1062. sdate date,
  1063. grade number(2) default 1,
  1064. class number(4),
  1065. email varchar2(50)
  1066. );
  1067. --可以给这个约束起一个名字:
  1068. create table stu(
  1069. id number(6),
  1070. name varchar2(20) constraint stu_name_nn not null,
  1071. sex number(1),
  1072. age number(3),
  1073. sdate date,
  1074. grade number(2) default 1,
  1075. class number(4),
  1076. email varchar2(50)
  1077. );
  1078.  
  1079. --唯一性约束
  1080. --email字段不应该有重复值
  1081. --unique约束只是代表该字段的值不能重复,但空值是允许的
  1082. create table stu(
  1083. id number(6),
  1084. name varchar2(20) constraint stu_name_nn not null,
  1085. sex number(1),
  1086. age number(3),
  1087. sdate date,
  1088. grade number(2) default 1,
  1089. class number(4),
  1090. email varchar2(50) unique
  1091. );
  1092. --可以给unique约束起一个名字:
  1093. create table stu(
  1094. id number(6),
  1095. name varchar2(20) constraint stu_name_nn not null,
  1096. sex number(1),
  1097. age number(3),
  1098. sdate date,
  1099. grade number(2) default 1,
  1100. class number(4),
  1101. email varchar2(50) constraint stu_email_uni unique
  1102. );
  1103. --还可以将约束加在字段定义完毕后
  1104. create table stu(
  1105. id number(6),
  1106. name varchar2(20) constraint stu_name_nn not null,
  1107. sex number(1),
  1108. age number(3),
  1109. sdate date,
  1110. grade number(2) default 1,
  1111. class number(4),
  1112. email varchar2(50),
  1113. constraint stu_email_uni unique(email)
  1114. );
  1115. --也可以在表级约束中用一个约束条件同时约束多个字段,
  1116. --比如我们要求email和名字的组合值不能重复
  1117. create table stu(
  1118. id number(6),
  1119. name varchar2(20) constraint stu_name_nn not null,
  1120. sex number(1),
  1121. age number(3),
  1122. sdate date,
  1123. grade number(2) default 1,
  1124. class number(4),
  1125. email varchar2(50),
  1126. constraint stu_email_uni unique(name, email)
  1127. );
  1128.  
  1129. --主键约束
  1130. --主键可以用来唯一的标识一条记录,
  1131. --主键相当于非空约束和唯一约束的组合,
  1132. --在一张表中只允许有一个主键,
  1133. --这个主键可以是一个或者多个子段的组合
  1134. create table stu(
  1135. id number(6) primary key,
  1136. name varchar2(20) constraint stu_name_nn not null,

  1137. email varchar2(50),
  1138. constraint stu_email_uni unique(name, email)
  1139. );
  1140. --主键可以定义在多个子段上,此时用这些字段的组合来标识唯一的一条记录,
  1141. --语法上只能够采用表级约束
  1142. create table stu(
  1143. id number(6),
  1144. name varchar2(20) constraint stu_name_nn not null,

  1145. email varchar2(50),
  1146. constraint stu_email_uni unique(name, email),
  1147. constraint stu_id_name_pk primary key (id, name)
  1148. );
  1149.  
  1150. --外键约束
  1151. --外键约束建立于一张表的两个字段或两张表的两个字段上,
  1152. --用于保证两个字段的关系,即:
  1153. ----子表外键字段的值必须在参照字段的取值中存在,
  1154. ----并且,如果字段的值被别的字段参照时,记录不允许被删除。
  1155. --外键约束被参考的字段必须是主键!
  1156.  
  1157. --违反完整约束条件
  1158. insert into emp (empno, ename, job, deptno)
  1159. values (9997, 'TEST', 'CLERK', 80);
  1160.  
  1161. --违反完整约束条件
  1162. delete from dept where deptno = 10;
  1163. select * from dept;
  1164.  
  1165. --建立另外一张表class,用来表示班级的信息,
  1166. create table class(
  1167. id number(4) primary key,
  1168. name varchar2(20) not null
  1169. );
  1170. --在创建stu表时加入外键约束:
  1171. --drop table stu;
  1172. create table stu(
  1173. id number(6),
  1174. name varchar2(20) constraint stu_name_nn not null,
  1175. sex number(1),
  1176. age number(3),
  1177. sdate date,
  1178. grade number(2) default 1,
  1179. class number(4) references class(id),
  1180. email varchar2(50) constraint stu_email_uni unique
  1181. );
  1182. --也可以采用表级约束语法:
  1183. create table stu(
  1184. id number(6),
  1185. name varchar2(20) constraint stu_name_nn not null,
  1186. sex number(1),
  1187. age number(3),
  1188. sdate date,
  1189. grade number(2) default 1,
  1190. class number(4),
  1191. email varchar2(50) constraint stu_email_uni unique,
  1192. constraint stu_class_fk foreign key (class) references class(id)
  1193. );
  1194. --违反完整约束条件
  1195. insert into stu
  1196. values (1, 'test', 0, 22, to_date('2005-03-02' , 'YYYY-MM-DD'), 1, 1, 'test@test.com')
  1197.  
  1198. --想插入stu表中任何的class的值,必须在class表中id字段找到,因此,我们首先执行下面的语句:
  1199. insert into class values (1, 'Class1');
  1200.  
  1201. --当stu表中已经有记录参照了class表中id1的记录时,违反完整约束条件
  1202. delete from class where id = 1;
  1203.  
  1204. --Check约束
  1205. --Check约束用于检验字段的值是否符合某个条件表达式,
  1206.  
  1207. --要求插入stu表中年龄字段的值不能为负数
  1208. create table stu(
  1209. id number(6),
  1210. name varchar2(20) constraint stu_name_nn not null,
  1211. sex number(1),
  1212. age number(3),
  1213. sdate date,
  1214. grade number(2) default 1,
  1215. class number(4),
  1216. email varchar2(50) constraint stu_email_uni unique,
  1217. constraint stu_class_fk foreign key (class)references class(id),
  1218. constraint stu_age_min check (age > 0)
  1219. );
  1220. --在Check约束中,条件表达式可以使用andornot等逻辑操作符。
  1221.  
  1222. create table stu(
  1223. id number(6) primary key,
  1224. name varchar2(20) not null,
  1225. sex number(1),
  1226. age number(3),
  1227. sdate date,
  1228. grade number(2) default 1,
  1229. class number(4),
  1230. email varchar2(50) unique,
  1231. constraint stu_class_fk foreign key (class)references class(id),
  1232. constraint stu_age_min check (age > 0)
  1233. );
  1234.  
  1235. --------------------------------------------------------------------------------------
  1236. --修改表结构或其约束条件-->即alter table语句,
  1237. --增加字段-----给stu表增加一个家庭住址的字段
  1238. alter table stu add (addr varchar2(100));
  1239. --删除字段-----例如要讲我们刚才新增的addr字段进行删除,
  1240. alter table stu drop (addr);
  1241. --修改字段-----例如我们要修改新增的addr字段的精度
  1242. --注意如果原来该字段中没有任何数据,那么可以将字段修改为任何类型,否则,所修改的类型必须能够容纳原有的数据。
  1243. alter table stu modify (addr varchar2(150));
  1244. --删除或增加约束条件
  1245. --删除stu表中的外键约束stu_class_fk,可以这样写:
  1246. alter table stu
  1247. drop constraint stu_class_fk;
  1248. --加入新的约束:
  1249. alter table stu
  1250. add constraint stu_class_fk foreign key (class) references class(id);
  1251. --注意-----非空约束不能够使用类似的语法,只能够通过修改字段来同时修改约束,例如:
  1252. --将name字段上的非空约束去除:
  1253. alter table stu modify (name varchar2(20) null);
  1254. --在name字段上添加非空约束:
  1255. alter table stu modify (name varchar2(20) not null);
  1256. --当无法确定一个约束的名字的时候,可以向系统表中寻找,有关系统表的操作,请参考附录《数据库常用DBA操作》,也可以将原来的表删除,然后建立新的表。
  1257. --select * from user_objects
  1258.  
  1259. --删除表
  1260. Drop table stu;
  1261.  
  1262. --索引是为了加快对数据的搜索速度而设立的,
  1263. --对stu表中的email字段建立索引
  1264. create index idx_stu_email on stu(email);
  1265. --对两个字段的组合建立索引,
  1266. create index idx_stu_email_class on stu(email, class);
  1267. --我们想删除刚刚建立的索引,可以这样写:
  1268. drop index inx_stu_email_class;
  1269.  
  1270. --视图
  1271. --不用视图-->非常复杂的查询语句(求平均薪水的等级最低的部门的部门名称):
  1272. select dname, grade from
  1273. (select deptno, avg_sal, grade from
  1274. (select deptno, avg(sal) avg_sal from emp group by deptno) t,
  1275. salgrade s
  1276. where
  1277. t.avg_sal between s.losal and s.hisal )
  1278. t1,
  1279. dept
  1280. where t1.deptno = dept.deptno
  1281. and
  1282. t1.grade =
  1283. (select min(grade) from
  1284. (select deptno, avg_sal, grade from
  1285. (select deptno, avg(sal) avg_sal from emp group by deptno) t,
  1286. salgrade s
  1287. where
  1288. t.avg_sal between s.losal and s.hisal )
  1289. );
  1290. --建立视图
  1291. create view v$_temp as
  1292. (select deptno, avg_sal, grade from
  1293. (select deptno, avg(sal) avg_sal from emp group by deptno) t,
  1294. salgrade s
  1295. where
  1296. t.avg_sal between s.losal and s.hisal );
  1297. --上面的查询就可以简化为:
  1298. select dname from dept, v$_temp where
  1299. v$_temp.deptno = dept.deptno
  1300. and grade = (select min(grade) from v$_temp);
  1301.  
  1302. --适当的利用视图,可以使我们的查询变得简单,
  1303. --但是如果视图建立的太多的话,会给我们系统的维护带来麻烦,
  1304. ----比如如果表的结构了,与这张表有关的任何视图必须跟着修改,
  1305.  
  1306. --删除一张视图的时候,
  1307. drop view v$_temp;
  1308.  
  1309. --序列----->序列是oracle专有的对象,它用来产生一个自动递增的数列,
  1310.  
  1311. create table article(
  1312. id number,
  1313. title varchar2(1024),
  1314. content long
  1315. );
  1316. ---创建序列
  1317. create sequence seq_article_id start with 1 increment by 1;
  1318. ---使用序列
  1319. ----select * from article
  1320. insert into article
  1321. values (seq_article_id.nextval, 'TEST', 'test content');
  1322.  
  1323. --删除序列
  1324. drop sequence seq_article_id;
  1325.  
  1326. --数据库设计
  1327. --BBS需求
  1328. --1,可以登陆,可以退出
  1329. --2,用户可以注册
  1330. --3,所有人可以发帖,可以回帖
  1331. --4,划分不同的板块
  1332. --5,每个板块有一个或多个版主,一个人可以是多个板块的版主
  1333. --select * from user;
  1334.  
  1335. create table tbl_user(
  1336. us_id number(6) primary key,
  1337. us_username varchar2(20),
  1338. us_password varchar2(20),
  1339. us_rdate date
  1340. );
  1341. create table tbl_board(
  1342. bd_id number(6) primary key,
  1343. bd_name varchar2(200),
  1344. bd_masterid varchar2(200)
  1345. );
  1346. create table tbl_topic(
  1347. tp_id number(6) primary key,
  1348. tp_title varchar2(200),
  1349. tp_content varchar2(4000),
  1350. tp_us_id number(6) references tbl_user(us_id),
  1351. tp_bd_id number(6) references tbl_board(bd_id),
  1352. tp_pid number(6),
  1353. tp_pdate date,
  1354. tp_rootid number(6)
  1355. );
  1356.  
  1357. --树状结构的设计
  1358. 1:id - pid
  1359.  
  1360. 2id - pid - isleaf - level - childcount
  1361. 递归效率增加
  1362. 插入、删除、修改效率降低
  1363. 支持平板形式支持的不好
  1364.  
  1365. 3:id - pid - isleaf - level - childcount - rootId
  1366. 平板形式好实现
  1367.  
  1368. 4id pid rootid 代表字符串(代表数字)
  1369. 最多每个节点能有99个小孩
  1370. 最多有3
  1371.  
  1372. 01 00 00 第一层第一个 01 00 00
  1373. 01 01 00 第一个回复 01 01 00
  1374. 01 02 00 01 01 01
  1375. 01 02 01 01 02 00
  1376. 01 01 01 01 02 01
  1377.  
  1378. --权限设计
  1379.  
  1380. 1: 资源Resource
  1381. 帖子,用户信息,板块信息
  1382. 2: 权限privilege
  1383. 发帖,删贴,回复帖,查询贴,添加用户,删除用户,查询用户,修改用户密码,修改用户信息,......
  1384. 2: 角色role,可以赋予多个权限
  1385. 一系列权限的组合
  1386. 3: 用户对应一到多个权限
  1387. 1:用户登陆
  1388. 2:验证属于什么角色
  1389. 3:检查该角色是不是具备操作权限
  1390.  
  1391. --简化的权限设计:用户表,角色表
  1392. --思考那些人会使用该系统?
  1393. --要站在使用者的角度去分析
  1394. create table tbl_role(
  1395. rl_id number(6) primary key,
  1396. rl_name varchar2(20),
  1397. rl_code date
  1398. );
  1399. create table tbl_user(
  1400. us_id number(6) primary key,
  1401. us_username varchar2(20),
  1402. us_password varchar2(20),
  1403. us_rdate date,
  1404. us_rl_id number(6) references tbl_role(rl_id),
  1405. );
  1406.  
  1407. declare - 可选
  1408. 声明各种变量或游标的地方。
  1409. begin - 必要
  1410. 开始执行语句。
  1411. --单行注释语句用两个连在一起的'-'表示。
  1412. /*多行注释语句,
  1413. 可以换行*/
  1414. exception - 可选
  1415. 出错后的处理。
  1416. end; - 必要(请注意end后面的分号)
  1417. 结束。
  1418.  
  1419. -----------------------------------------------------------------------------
  1420. --最简单的语句块
  1421. begin
  1422. dbms_output.put_line('HelloWorld!');
  1423. end;
  1424.  
  1425. set serveroutput on;
  1426.  
  1427. -------------------------------------------------------------------------------
  1428. --简单的PL/SQL语句块
  1429.  
  1430. declare
  1431. v_name varchar2(20);
  1432. begin
  1433. v_name := 'myname';
  1434. dbms_output.put_line(v_name);
  1435. end;
  1436.  
  1437. ---------------------------------------------------------------------------
  1438. --语句块的组成
  1439. declare
  1440. v_num number := 0;
  1441. begin
  1442. v_num := 2/v_num;
  1443. dbms_output.put_line(v_num);
  1444. exception
  1445. when others then
  1446. dbms_output.put_line('error');
  1447. end;
  1448.  
  1449. --在变量声明时需要遵守一些基本的规则:
  1450. 1. 变量名不能够使用保留字,如from select
  1451. 2. 第一个字符必须是字母
  1452. 3. 变量名最多包含30个字符
  1453. 4. 不要与数据库的表或者列同名
  1454. 5. 每一行只能声明一个变量
  1455. --PL/SQL中的变量类型主要有以下几种:
  1456. 1. binary_integer:整数,主要用来计数而不是用来表示字段类型
  1457. 2. number:数字类型
  1458. 3. char:定长字符串
  1459. 4. varchar2:变长字符串
  1460. 5. date:日期
  1461. 6. long:长字符串,最长2GB
  1462. 7. boolean:布尔类型,可以取值为truefalsenull
  1463.  
  1464. --变量声明
  1465. declare
  1466. v_temp number(1):=5;
  1467. v_count binary_integer := 0;
  1468. v_sal number(7,2) := 4000.00;
  1469. v_date date := sysdate;
  1470. v_pi constant number(3,2) := 3.14; --相当于java里面的final
  1471. v_valid boolean := false;
  1472. v_name varchar2(20) not null := 'MyName';
  1473. begin
  1474. dbms_output.put_line('v_temp value:' || v_name);
  1475. end;
  1476.  
  1477. --变量声明,使用%type属性
  1478. declare
  1479. v_empno number(4);
  1480. v_empno2 emp.empno%type; --好处,表的定义变了,这里跟着变
  1481. v_empno3 v_empno2%type;
  1482. begin
  1483. dbms_output.put_line('Test');
  1484. end;
  1485.  
  1486. --简单变量赋值
  1487. declare
  1488. v_name varchar2(20);
  1489. v_sal number(7,2);
  1490. v_sal2 number(7,2);
  1491. v_valid boolean := false;
  1492. v_date date;
  1493. begin
  1494. v_name := 'MyName';
  1495. v_sal := 23.77;
  1496. v_sal2 := 23.77;
  1497. v_valid := (v_sal = v_sal2);
  1498. v_date := to_date('1999-08-12 12:23:38', 'YYYY-MM-DD HH24:MI:SS');
  1499. --dbms_output.put_line(v_sal == v_sal2);
  1500. end;
  1501.  
  1502. --复合变量
  1503. --Table变量类型
  1504. --相当于java里面的数组
  1505. declare
  1506. --声明了一个数组类型,约定俗成以type_开头
  1507. --下标的类型是binary_integer类型
  1508. type type_table_emp_empno is table of emp.empno%type index by binary_integer;
  1509. v_empnos type_table_emp_empno;
  1510. begin
  1511. v_empnos(0) := 7369;
  1512. v_empnos(2) := 7839;
  1513. v_empnos(200) := 9999; --下标可以取负值
  1514. dbms_output.put_line(v_empnos(200));
  1515. end;
  1516.  
  1517. --Record变量类型
  1518. --相当于java里面的类
  1519. declare
  1520. type type_record_dept is record
  1521. (
  1522. deptno dept.deptno%type,
  1523. dname dept.dname%type,
  1524. loc dept.loc%type
  1525. );
  1526. v_temp type_record_dept;
  1527. begin
  1528. v_temp.deptno := 50;
  1529. v_temp.dname := 'aaaa';
  1530. v_temp.loc := 'bj';
  1531. dbms_output.put_line(v_temp.deptno || ' ' || v_temp.dname);
  1532. end;
  1533.  
  1534. --使用%rowtype声明record变量
  1535. --表结构变了,这段程序不用变
  1536. declare
  1537. v_temp dept%rowtype;
  1538. begin
  1539. v_temp.deptno := 50;
  1540. v_temp.dname := 'aaaa';
  1541. v_temp.loc := 'bj';
  1542. dbms_output.put_line(v_temp.deptno || ' ' || v_temp.dname);
  1543. end;
  1544.  
  1545. --SQL语句的运用
  1546. --select必须返回一条记录并且只能返回一条记录
  1547. --select必须和into一起用
  1548. declare
  1549. v_ename emp.ename%type;
  1550. v_sal emp.sal%type;
  1551. begin
  1552. select ename,sal into v_ename,v_sal from emp where empno = 7369;
  1553. dbms_output.put_line(v_ename || ' ' || v_sal);
  1554. end;
  1555. --ORA-01403: 未找到数据
  1556. declare
  1557. v_ename emp.ename%type;
  1558. v_sal emp.sal%type;
  1559. begin
  1560. select ename,sal into v_ename,v_sal from emp where empno = 9999;
  1561. dbms_output.put_line(v_ename || ' ' || v_sal);
  1562. end;
  1563. --实际返回的行数超出请求的行数
  1564. declare
  1565. v_ename emp.ename%type;
  1566. v_sal emp.sal%type;
  1567. begin
  1568. select ename,sal into v_ename,v_sal from emp where deptno = 30;
  1569. dbms_output.put_line(v_ename || ' ' || v_sal);
  1570. end;
  1571.  
  1572. --v_emp可以存贮一条记录
  1573. declare
  1574. v_emp emp%rowtype;
  1575. begin
  1576. select * into v_emp from emp where empno = 7369;
  1577. dbms_output.put_line(v_emp.ename);
  1578. end;
  1579.  
  1580. --insert
  1581. declare
  1582. v_deptno dept.deptno%type := 50;
  1583. v_dname dept.dname%type := 'aaaa';
  1584. v_loc dept.loc%type := 'bj';
  1585. begin
  1586. insert into dept2 values (v_deptno, v_dname, v_loc);
  1587. commit;
  1588. end;
  1589.  
  1590. select * from dept2;
  1591.  
  1592. --sql%rowcount
  1593. declare
  1594. v_deptno emp2.deptno%type := 30;
  1595. v_count number;
  1596. begin
  1597. --update emp2 set sal = sal/2 where deptno = v_deptno;
  1598. --delete from emp2 where deptno = 10;
  1599. --select deptno into v_deptno from emp2 where empno = 7369 ;
  1600. select count(*) into v_count from emp2;
  1601. dbms_output.put_line(sql%rowcount || '条记录被影响');
  1602. --commit;
  1603. end;
  1604.  
  1605. rollback;
  1606.  
  1607. --PL/SQL使用DDL语句
  1608. --必须写execute immediate......
  1609. begin
  1610. execute immediate 'create table T (nnn varchar2(20) default ''aaa'')';
  1611. end;
  1612.  
  1613. drop table T;
  1614. -------------------------------------------------------------------------------------------------------------------
  1615.  
  1616. --if语句
  1617. --取出7369的薪水,如果<1200,则输出'low',如果<2000则输出'middle',否则'high'
  1618. --注意elsif的写法
  1619. --注意else后面没有then
  1620. --注意end if后面有一个分号
  1621. declare
  1622. v_sal emp.sal%type;
  1623. begin
  1624. select sal into v_sal from emp
  1625. where empno = 7369;
  1626. if (v_sal < 1200) then
  1627. dbms_output.put_line('low');
  1628. elsif(v_sal < 2000) then
  1629. dbms_output.put_line('middle');
  1630. else
  1631. dbms_output.put_line('high');
  1632. end if;
  1633. end;
  1634.  
  1635. --IF
  1636. --FI
  1637.  
  1638. --循环
  1639. --第一种
  1640. declare
  1641. i binary_integer := 1;
  1642. begin
  1643. loop
  1644. dbms_output.put_line(i);
  1645. i := i + 1;
  1646. exit when ( i >= 11);
  1647. end loop;
  1648. end;
  1649.  
  1650. --第二种
  1651. declare
  1652. j binary_integer := 1;
  1653. begin
  1654. while j < 11 loop
  1655. dbms_output.put_line(j);
  1656. j := j + 1;
  1657. end loop;
  1658. end;
  1659.  
  1660. --第三种
  1661. begin
  1662. for k in 1..10 loop
  1663. dbms_output.put_line(k);
  1664. end loop;
  1665.  
  1666. for k in reverse 1..10 loop
  1667. dbms_output.put_line(k);
  1668. end loop;
  1669. end;
  1670.  
  1671. ---------------------------------------------------------------------
  1672.  
  1673. --错误处理1
  1674. --这条select,返回多条记录,会产生异常
  1675. declare
  1676. v_temp number(4);
  1677. begin
  1678. select empno into v_temp from emp where deptno = 10;
  1679. exception
  1680. when too_many_rows then
  1681. dbms_output.put_line('太多记录了');
  1682. when others then
  1683. dbms_output.put_line('error');
  1684. end;
  1685. --错误处理2
  1686. declare
  1687. v_temp number(4);
  1688. begin
  1689. select empno into v_temp from emp where empno = 2222;
  1690. exception
  1691. when no_data_found then
  1692. dbms_output.put_line('没数据');
  1693. end;
  1694. --------------------------------------------------------------------------------------------------------------------
  1695. --游标 (重点)
  1696.  
  1697. --open c 的时候,才执行select语句
  1698. declare
  1699. cursor c is
  1700. select * from emp;
  1701. v_emp c%rowtype;
  1702. begin
  1703. open c;
  1704. fetch c into v_emp;
  1705. dbms_output.put_line(v_emp.ename);
  1706. close c;
  1707. end;
  1708. --最常用的游标属性有以下四个:
  1709. --1. %isopenboolean类型变量,用来代表游标是否打开。
  1710. --2. %notfoundboolean类型变量,如果最近的fetch语句没有返回一条记录,取true
  1711. --3. %foundboolean类型变量,如果最近的fetch语句取到了记录,取true
  1712. --4. %rowcountnumber类型变量,用来代表目前fetch到的记录的总行数。
  1713.  
  1714. declare
  1715. cursor c is
  1716. select * from emp;
  1717. v_emp c%rowtype;
  1718. begin
  1719. open c;
  1720. loop
  1721.  
  1722. fetch c into v_emp;
  1723. exit when (c%notfound);
  1724. dbms_output.put_line(v_emp.ename);--如果这行挪到上边,最后一行打印两遍
  1725.  
  1726. end loop;
  1727. close c;
  1728. end;
  1729. --while
  1730. declare
  1731. cursor c is
  1732. select * from emp;
  1733. v_emp c%rowtype;
  1734. begin
  1735. open c;
  1736. fetch c into v_emp;
  1737. while (c%found) loop
  1738. dbms_output.put_line(v_emp.ename);
  1739. fetch c into v_emp;--如果这行挪到上边,最后一行打印两遍
  1740.  
  1741. end loop;
  1742. close c;
  1743. end;
  1744. --for.自动打开,自动关闭
  1745. --最简单的,不容易出错
  1746. declare
  1747. cursor c is
  1748. select * from emp;
  1749. begin
  1750. for v_emp in c loop
  1751. dbms_output.put_line(v_emp.ename);
  1752. end loop;
  1753. end;
  1754.  
  1755. --带参数的游标
  1756. --声明两个行参
  1757. --v_temp c%rowtype;--不需要声明
  1758. declare
  1759. cursor c(v_deptno emp.deptno%type, v_job emp.job%type)
  1760. is
  1761. select ename, sal from emp where deptno = v_deptno and job = v_job;
  1762. --v_temp c%rowtype;
  1763. begin
  1764. --open c(30, 'CLERK');
  1765. for v_temp in c(30, 'CLERK') loop
  1766. dbms_output.put_line(v_temp.ename);
  1767. end loop;
  1768.  
  1769. end;
  1770.  
  1771. --可更新的游标
  1772. --用的不多
  1773. --注意:for update
  1774. --注意游标的用法:where current of c,
  1775. --判断两个值是不是相等,用一个等号
  1776. declare
  1777. cursor c
  1778. is
  1779. select * from emp2 for update;
  1780. --v_temp c%rowtype;
  1781. begin
  1782.  
  1783. for v_temp in c loop
  1784. if(v_temp.sal < 2000) then
  1785. update emp2 set sal = sal * 2 where current of c;
  1786. elsif (v_temp.sal = 5000) then
  1787. delete from emp2 where current of c;
  1788. end if;
  1789. end loop;
  1790. commit;
  1791. end;
  1792. ----------------------------------------------------------------------------------------------------------------------
  1793. --存储过程
  1794. --带名字的plsql程序块
  1795. create or replace procedure p
  1796. is
  1797. cursor c is
  1798. select * from emp2 for update;
  1799. begin
  1800. for v_emp in c loop
  1801. if (v_emp.deptno = 10) then
  1802. update emp2 set sal = sal + 10 where current of c;
  1803. elsif (v_emp.deptno = 20) then
  1804. update emp2 set sal = sal + 20 where current of c;
  1805. else
  1806. update emp2

sql 使用汇总(PQSQL)的更多相关文章

  1. SQL小汇总

    SQL小汇总 1.对每个时段的数据进行统计2.查询时间条件(to_date)3.插入序列号和系统时间4.查询当天.7天内.30天内5.查询前后x小时.分钟.天.月.6.保留小数点后4位7.查询字段A中 ...

  2. SQL语句汇总(终篇)—— 表联接与联接查询

    上一篇博文说到相关子查询效率低下,那我们怎么能将不同表的信息一起查询出来呢?这就需要用到表联接. 和之前的UNION组合查询不同,UNION是将不同的表组合起来,也就是纵向联接,说白了就是竖着拼起来. ...

  3. SQL语句汇总(一)——数据库与表的操作以及创建约束

    首先,非常感谢大家对上篇博文的支持,真是让本菜受宠若惊,同时对拖了这么久才出了此篇表示抱歉. 前言:此文旨在汇总从建立数据库到联接查询等绝大部分SQL语句.SQL语句虽不能说很多,但稍有时间不写就容易 ...

  4. 初级SQL开发汇总指南

    汇总部分内容来自网络(作者  :zhtbs),比较基础的东西,能够了解比较基础的一些东西. Select语句概要 数据库中数据的提取(查询)使用select 语法,主要有以下几点作用 l  提取的数据 ...

  5. SQL语句汇总(终篇)—— 表联接与联接查询

    既然是最后一篇那就不能只列出些干枯的标准语句,更何况表联接也是SQL中较难的部分,所以此次搭配题目来详细阐述表联接. 上一篇博文说到相关子查询效率低下,那我们怎么能将不同表的信息一起查询出来呢?这就需 ...

  6. SQL语句汇总(一)——数据库与表的操作以及创建约束

    首先,非常感谢大家对上篇博文的支持,真是让本菜受宠若惊,同时对拖了这么久才出了此篇表示抱歉. 前言:此文旨在汇总从建立数据库到联接查询等绝大部分SQL语句.SQL语句虽不能说很多,但稍有时间不写就容易 ...

  7. SQL练习题汇总(Sqlserver和Mysql版本)

    所需表及数据执行脚本: CREATE TABLE STUDENT (SNO ) NOT NULL, SNAME ) NOT NULL, SSEX ) NOT NULL, SBIRTHDAY DATET ...

  8. MS SQL 分类汇总参数 grouping(**)=1 rollup cubt

    转:http://www.111cn.net/database/mssqlserver/43368.htm 本文章介绍了关于sql多级分类汇总实现方法及数据结构,有碰到问题的同学可参考一下. 据库结构 ...

  9. 基本Sql语句汇总

    关于Sql语句的学习,选择的DBMS为SQL Server,Sql语句随着工作中的应用不断补充,不具备系统性,为个人笔记汇总,网上有很多优秀的资源,故不对每一处应用做过多细致的说明,后期会对部分篇幅较 ...

随机推荐

  1. 「DP」区间dp

    区间dp? 状态设计为描述一段区间的dp. eg:f[i][j]表示从 i 到 j 这个区间上的最优值.

  2. CopyOnWrite 策略

    CopyOnWrite 是用于解决并发读写的一种策略,在Write的时候对共享变量进行Copy,在副本上进行更新,再把更新好的副本原子性地替换原来的共享变量.写入时复制是一种优化策略,多个调用者同时访 ...

  3. EF Core的安装、EF Core与数据库结合

    一.新建一个.net core的MVC项目                         新建好项目后,不能像以前一样直接在新建项中添加ef, 需要用命令在添加ef的依赖      二.EF Cor ...

  4. 201621123016《Java程序设计》第1周学习总结

    1. 本周学习总结 本周的学习内容:java的发展历史,java程序设计环境,java简单语法. java与c++一样是一门面向对象的程序设计语言(相比于c++它是一门更彻底的面向对象的程序设计语言) ...

  5. swift4.0 方法监听Selector写法总结

    import UIKit class MainViewController: UITabBarController { //MARK:属性 懒加载 lazy var composeBtn = UIBu ...

  6. HDU2896【AC自动机-模板】

    思路: 因为不同病毒特征码不会相同. AC自动机,然后对于每一个输出即可. 注意:以上字符串中字符都是ASCII码可见字符(不包括回车);G++ MLE. //#include <bits/st ...

  7. Android DPAD not enabled in AVD

    问题描述:打开Android的仿真器,右侧的按键部分对于上下左右键出现以下现象后果是,这些按键都没法使用,由于我是测试一个小游戏,俄罗斯方块,朋友,要是少了上下左右键,让我情何以堪,而且我试过使用键盘 ...

  8. mysql 5.6 安装x64版本

    从mysql下载的 32bit的 msi installer 后 , 安装的时候没有发现选择x64的地方, 最后安装完毕后发现server是32bit的,只能删除server(  installer ...

  9. hdu1536(sg函数)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1536 题意:首先输入K 表示一个集合的大小  之后输入集合 表示对于这对石子只能去这个集合中的元素的个 ...

  10. c#file类读写

    private void button4_Click(object sender, EventArgs e) { FileStream fs = File.OpenRead(textBox1.Text ...