Oracle SQL与PL/SQL学习笔记(-)

时间:2021-01-16 05:15:24

本文主要为参考文献[1]的学习笔记。

Oracle  SQLPL/SQL笔记

 

 

第1章            开始使用Oracle Server

1.Oracle Database的安装

Ø        指定Oracle主目录位置。

Ø        不创建启动数据库。

Ø        选择企业版。

2. 建立数据库

Ø        开始->菜单->Oracle->OraDb10g_home1->Configuration and Migration Tools->Database Configuration Assistant.

Ø        输入全局数据库名和数据库例程SID

Ø        设置账号和口令,其它选项接收默认即可。

3. 使用Net Manager配置监听程序和网络服务名

Ø        开始->菜单->Oracle->OraDb10g_home1->Configuration and Migration Tools->Net Manager

Ø        在默认监听程序Listener中添加数据库。输入主机IP地址或主机名,监听端口1521。数据库服务中输入全局数据库名,Oracle主目录和SID

Ø        重启监听程序。在Windows操作系统的服务中重启OracleOraDb10g_home1TNSListener服务。

Ø        Net Manager的“服务命名”中点击加号形状的按钮。输入Net服务名,主机名,1521端口及SID

4 sql*plus工具

Ø        命令行语法:sqlplus [username]/[passwd] [@server] [AS SYSDBA] [AS SYSOPER]

Ø        连接数据库:d:/> sqlplus scott/tiger@demo

Ø        窗口环境的sql*plus:开始->菜单->Oracle->OraDb10g_home1->Application Development->SQL Plus.

Ø        浏览器环境的isql*plus:需启动isqlplus*plus服务器:isqlplusctl start;访问URL http://hostname:port/isqlplus即可。

5 PL/SQL Developer

       PL/SQL集成开发环境。其中命令窗口实现了sql*plus的全部功能。

第2章            SQLPL/SQL综述

1 数据库基本概念

数据库管理系统:支持三级结构两级映射的数据管理软件。

数据库:由数据库管理系统管理,具有较少冗余,较高独立性、支持多用户共享、并且有相互联系的文件的集合。

三级数据视图:数据抽象的三个层次,外部视图、全局视图、存储视图。

两级映射:外部视图与全局视图间的逻辑映射;全局视图与存储视图之间的物理映射。

模式:使用DDL精确定义数据视图的程序。

三级模式:子模式(外模式);模式(逻辑模式);内模式(物理模式)。

数据模型:抽象描述现实世界的方法,表示实体和实体之间的联系。

关系模型:用二维表格数据表示实体和实体之间联系的模型。

关系:关系模型中的一张二维表。元组,属性,属性名,域。

关系模式:关系的表头,即关系中属性名的集合,为关系的型。

DBMS组成:DDLDML;数据库管理例行程序。

数据字典:数据库系统中涉及到的对象的描述信息,以数据文件的形式组织起来。

数据库系统:数据库、DBMSDBA和应用系统组成的集合。

2 SQL标准

       SQl-89, SQL-92, SQL-99SQL99标准是ANSIISO, IEC标准,分5个部分(Part1:SQL/Framework, Part2: Foundation/SQL Foundation, Part4: Persistent Stored Modules(SQL/PSM), Part5: Host Language Binding(SQL/Bindings)。一般一百页左右,最厚的第二部分超过一千页。描述貌似使用的是BNF范式。

3 SQl语言分类

Ø        数据查询语言(SELECT

Ø        数据操纵语言(DML:INSERT, UPDATE, DELETE

Ø        数据定义语言(DDL: CREATE, ALTER, DROP

Ø        数据控制语言(DCL: GRANT REVOKE

Ø        事务控制语句(TCS):COMMIT, ROLLBAK, SAVEPOINT

Ø        会话控制语句(SCL: ALTER SESSION, SET ROLE

Ø        系统控制语句(SCS: ALTER SYSTEM

4 Oracle数据库对象

       表、索引、约束、视图、序列、同义词、过程、函数、触发器、对象类型。

第3章            基本查询语句

1 查询所有列

SELECT * FROM table_name;

2 查询指定列

SELECT column1,..., columnN FROM table_name;

3 使用列别名与表别名

SELECT alias.column1 [AS] aliasOfCol1, ... , alias.columnN aliasOfColN FROM table_name alias;

列别名含特殊字符时使用双引号。

4 排除重复行

SELECT DISTINCT column1,... ,column2 FROM table_name;

5 处理NULL

Ø        当插入数据时未提供值,且该列没有默认值时,该列结果为NULL.

Ø        使用NVL函数提供默认值;NVL(X,Y)表示列XNULL时返回Y

Ø        NVL2; NVL2(X, Y, Z)表示XNULL时返回Y,NULL时返回Z

6查询日期列

Ø        设置会话的日期的语言显示格式:

ALTER SESSION SET nls_date_language = 'SIMPLIFIED CHINESE';

ALTER SESSION SET nls_date_language = 'AMERICAN';

Ø        设置会话的日期的显示格式:

ALTER SESSION SET nls_date_format = 'YYYY''-''MM''-''DD';

Ø        使用TO_CHAR定制日期的显示格式:

SELECT t.crtime, TO_CHAR(t.crtime, 'YYYY-MM-DD') FROM table_name t;

7 连接字符串

Ø        ||: SELECT col1 || col2 FROM table_name;

Ø        CONCAT: SELECT CONCAT(col1, col2) FROM table_name;

 

 

第4章            限制数据

1 WHERE子句中使用常规比较符:>, <, >=, <=, !=, <>, =

Ø        注意这里的等于(=)不是C语言里的等于(==),另外不等于有两个:<> !=

Ø        常规比较符可用于数字,字符串,日期。字符串必须使用单引号。

Ø        SELECT * FROM emp WHERE hiredate > to_date('2009-11-07', 'YYYY-MM-DD');

Ø        SELECT * FROM emp WHERE UPPER(job) = 'CLEARK';

2 其它比较操作符

Ø        BETWEEN AND操作符指定范围

Ø        LIKE操作符模糊匹配字符串

       %表示0个或多个字符;

       _表示单个字符;

       ESCAPE 'char' 用于指定转义符,转义符后跟%_用于取消它们的特殊含义。

例如:

       SELECT * FROM emp WHERE ename LIKE '%a_%' ESCAPE 'a';

用来查询ename中包含下划线的记录。

Ø        IN操作符,匹配列表中的项。

       SELECT * FROM protocol t WHERE t.type IN ('HTTP', 'DNS', 'FTP');

Ø        IS NULL操作符:检测结果是否为NULL

Ø        逻辑操作符AND, OR, NOT.. 优先级NOT>AND>OR。可使用括号改变计算的优先级。NOT用于对特定条件取反,IS NOT NULL是最常见的。一个不恰当的例子如下:

       WHERE X AND (NOT (Y<Z))等价于WHERE X AND Y>=Z.

3 示例

       Rownum是一个伪列,表示符合条件的记录的序号。

Ø        SELECT * FROM table_name WHERE rownum < n;  --可用<=, n>1时正确。

Ø        SELECT * FROM table_name WHERE rownum < n;  --只有n = 1时正确。

Ø        SELECT * FROM table_name WHERE rownum > n;  -- n>0时为空集,n = 0时为全集。

Ø        查询符合条件的第XX条到第YY条记录:

       SELECT XX, YY FROM

       (SELECT XX, YY, rownum AS XYZ FROM table_name WHERE ZZ >20)

       WHERE XYZ BETWEEN 10 AND 20;

       另一种方式,使用集合间的差,可能比上面的使用子查询更耗资源:

       SELECT XX, YY FROM table_name WHERE ZZ>20 AND rownum < 20

       MINUS

       SELECT XX, YY FROM table_name WHERE ZZ>20 AND rownum < 10;

Ø         查询某个时间段的数据

       SELECT * FROM tablename t

       WHERE t.crtime BETWEEN

              TO_DATE('2009-11-10 11:00:00', 'YYYY-MM-DD HH24:MI:SS')

       AND

              TO_DATE('2009-11-10 12:00:00', 'YYYY-MM-DD HH24:MI:SS')

       ORDER BY t.crtime DESC;

 

 

第5章            排序数据

1 ORDER BY子句

Ø        ORDER BY col1 [ASC|DESC], ... , colN [ASC|DESC]

Ø        Order by子句必须为SELECT的最后一个子句。

Ø        ORDER BY可跟一列或多列排序;默认为升序(ASC, DESC表示降序。

Ø        若排序列有NULL,升序排列时,NULL行在最后面,降序排列时,NULL行在最前面。

Ø        使用多列排序:SELECT * FROM emp ORDER BY deptno ASC, sal DESC;

Ø        使用列位置排序,列位置从1开始:SELECT * FROM emp ORDER BY 1 DESC;

 

第6章            SQL单行函数

1 单行函数指输入一行,输出一行的函数,多行函数指输入多行输出一行的函数。单独调用单行函数时可使用数据字典dual

Ø        函数很多,最好下一个函数手册可供参考。PL/SQL Developer中键入函数时,会有参数说明。不知道有没有像类似man这样的官方手册。这里只做简单的列举。

2 数字函数

Ø        很多语言的数字函数名称都差不多。

Ø        ROUND:四舍五入,例如ROUND(AVG(t.salary),6)保留6位小数。

Ø        TRUNC:截断

Ø        SIG: 符号函数,负数-1,整数10返回0.

3 字符函数

Ø        SQL函数返回的CHAR或者VARCHAR2值超出长度限制,则会被截断并返回。如果返回的CBLOB值超出长度限制则显示错误消息。

Ø        UPPERLOWER用于大小写转换

Ø        INSTR用于字串查找,类似与C中的strstrC++中的find.

       SELECT instr('Great Wall In China', 'China') FROM dual;

Ø        SUBSTR用于得到字串。

Ø        LPAD,RPAD用于左右填充。

Ø        TREAM用于截断指定字符,例如

       SELECT * FROM fault_type d WHERE TRIM(trailing ' ' from d.type_desc) = 'INVALID_PARM';

为截取尾部空格的例子。默认时为截取头部和尾部。可分别指定leading, trailing, both

4 日期函数

Ø        SYSDATE: 返回当前系统时间。

5 转换函数

Ø        TO_CHAR: 将其它类型转换为字符串

Ø        TO_DATE:将字符串转换为日期

Ø        TO_NUMBER: 转换为NUMBER

6正则式函数

Ø        Oracle基于POSIXUnicode标准实现了正则表达式。如果已经熟悉了grep,应该可以找到熟悉的感觉。

Ø        各种字符样式:

       .: 匹配单个字符

       +:匹配该符号前出现一次或多次的子表达式。

       ?匹配该符号前出现一次或0次的子表达式。

       *:匹配该符号前出现0次或多次的子表达式。

       {m, n}:匹配该符号前出现至少m次,不超过n次的子表达式。

       []:用于匹配列表中的任意字符。列表中以^开头表示取反。

       |:用于匹配二选一。

       ():括号内表达式作为一个单元。

       /n;匹配该符号前第n次重复出现的子表达式。

       /:取消元字符的特殊含义。

       ^$匹配字符串的开始和结束。

       [:class:]:用于匹配POSIX类别,例如upperdigit, alnum, space等。

       /d/D:用于匹配数字字符和非数字字符。

       /w/W:用于匹配单词和非单词。

       /s/S:用于匹配空格和非空格。

       /A用于匹配字符串的开始

       /Z/z用于匹配字符串的结束。

Ø        正则式函数:REGXP_LIKE, REGXP_INSTR, REGXP_SUBSTR, REGXP_REPLACE

 

第7章            操纵数据

       本章主要为数据控制语言DML和事务控制语句TCS

       使用中字符串需用单引号括起来。

1 INSERT语句

1)语法:

       INSERT INTO table_name [column1,...,columnN] VALUES(value1,...valueN);

2)不指定列列表时,需按顺序为所有列提供数据。

       INSERT INTO dept VALUES(50, 'TRAIN', 'BOSTON');

3)使用列列表时,只需为相应列增加数据即可。必须为主键列和非空列提供数据。

       INSERT INTO emp(empno, empname, hiredate)

       VALUES(1355, 'MARK', TO_DATE('2008-07-01', 'YYYY-MM-DD'));

       可使用DEFAULT代替VALUES中的值,若有默认值则为默认值,否则为NULL

4Oracle中使用替代变量插入数据:

       编写脚本C:/loademp.sql,内容如下:

       ACCEPT no PROMPT '请输入雇员号:';

       ACCEPT no PROMPT '请输入雇员名:';

       INSERT INTO emp(empno, empname) VALUES(&no, '&name');

       说明:

       ACCEPT 语句用于读取输入的数据,PROMPT后跟的是提示语句;

       VALUES中的&类似与C语言中scanf的读取输入,字符串不要忘了加单引号。

       加载此脚本时,在PL/SQL Developer的命令窗口中键入命令:@c:/loademp即可。或者直接将脚本内容复制到命令窗口也可以。

2 子查询复制数据

       (1)常规装载方式,可使用目标表的HWM(High Water Mark)以下空间。可提高表段空间利用率,但速度较慢。

       INSERT INTO employee(empno, ename, sal, deptno)

       SELECT empno, ename, sal, deptno FROM emp WHERE deptno = 20;

       (2)直接装载方式,不能使用目标表HWM,但速度很快。

       INSERT /*+APPEND*/ INTO employee(empno, ename, sal, deptno)

       SELECT empno, ename, sal, deptno FROM emp WHERE deptno = 20;

3 INTO子句中使用子查询

       INSERTINTO子句中可以指定表,视图和子查询。使用WITH CHECK OPTION选项,表示限制被插入的数据满足子查询的条件。

       INSERT INTO SELECT empno, ename, sal, deptno FROM emp

       WHERE deptno = 30 WITH CHECK OPTION)

       VALUES(1112, 'MARY', 2000, 30);

       此时数据被插入到子查询的基本表中。

4 多表插入

       多表插入表示用子查询将一张表的数据根据条件插入到多张表中。

1)无条件INSERT ALL

       将子查询的所有结果无条件的复制到多个表中。

       INSERT ALL

       INTO sal_history VALUES(ename, hiredate, sal)

       INTO mgr_history VALUES(ename, mgr, sal)

       SELECT ename hiredate, mgr, sal FROM emp;

2)有条件INSERT ALL

       将子查询的结果根据不同的条件插入到不同的表中

       INSERT ALL

       WHEN sal > 1000 THEN

       INTO sal_history VALUES(ename, hiredate,sal)

       WHEN mgr > 7000 THEN

       INTO mgr_history VALUES(ename, mgr, sal)

       SELECT ename, hiredate, mgr, sal FROM emp;

       这里的WHEN相当与C语言中的多个独立的if条件。

3)有条件INSERT FIRST

       INSERT ALL

       WHEN sal > 3000 THEN

       INTO sal_history VALUES(ename, hiredate,sal)

       WHEN mgr > 1000 THEN

       INTO mgr_history VALUES(ename, mgr, sal)

       ELSE

       INTO low_history VALUES(ename, hiredate, sal)

       SELECT ename, hiredate, mgr, sal FROM emp;

       这里的WHEN相当C语言中的if..else if...else if...else.

5 UPDATE更新数据

1)表达式更新数据

       UPDATE emp SET sal = sal*1.1, comm. = sal*0.1 WHERE deptno = 20;

2)子查询更新

       UPDATE emp SET (job, sal, comm.) = (

              SELECT job, sal, comm. FROM emp WHERE ename = 'SMITH')

       WHERE ename = 'SCOTT';

 

       --复制表数据

       UPDATE employee SET deptno = (

              SELECT deptno FROM emp WHERE empno = 7799)

       WHERE job = (SELECT job FROM emp WHERE empno = 7799);

6 使用MERGE语句

       若行存在,则执行UPDATE,否则执行INSERT, ON用于指定连接条件.

       MERGEI NTO new n USING emp e

       ON (n.empno = e.empno)

       WHEN MATCHED THEN

              UPDATE SET n.sal = e.sal

       WHEN NOT MATCHED THEN

              INSERTn.empno, n.ename, n.sal, n.comm

              VALUES(n.empno, e.ename, e.sal, e.comm);

7 删除数据

       DELETE删除不会释放表空间,TRUNCATE会释放表空间,DROP会删除表结构。

1)条件删除

       DELETE FROM emp WHERE ename = 'SCOTT';

2)删除所有数据

       DELETE FROM emp;

3)截断表

       TRUNCATE TABLE emp;

4)使用子查询删除数据

       DELETE FROM emp WHERE deptno = (SELECT deptno FROM dept WHERE dname = 'SALES')

       DELET删除主表数据时,需确保从表不存在相关记录。

8 事务控制

1)执行事务操作DML时,Oracle会在表上加锁,防止表结构被更改;同时被作用的行上加锁,防止其它事务在相应行执行DMLCOMMIT后会结束事务,删除保存点,释放锁。

2)提交事务:COMMIT;

       回退事务:ROLLBACK;

       设置保存点:

              SAVEPOINT point_name;

              exec dbms_transaction.savepoint('point_name');

       取消部分事务

              ROLLBACK TO point_name;

              exec dbms_transaction.rollback;

3)只读事务

       只读事务不会取得新的数据变化,用于取得具体时间点的数据。

       SET TRANSACTION READ ONLY;

       exec dbms_transaction.read_only;

4)顺序事务

       只读事务,使得会话不能执行DML操作。为了允许DML操作,可使用顺序事务。

       SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

       设置只读事务和顺序事务时,SET语句必须为事务开始的第一条语句。即之前的DML语句必须COMMIT后才能继续SET语句。

第8章             连接查询

1 等值连接

       SELECT dept.dname, emp.ename, emp.sal FROM emp, dept

       WHERE emp.deptno = dept.deptno AND dept.deptno = 10;

2 不等连接

       使用等值比较符号之外的其它比较操作符。如BETWEEN...AND

3 自连接

       主要用于显示上下级或层次关系。

       SELECT worker.ename, manager.ename

       FROM emp worker, emp manager

       WHERE worker.mgr = manager.deptno;

4 外连接

Ø        不仅返回满足条件的记录,而且返回不满足条件的部分记录。

Ø        使用+号,如WHERE table1.col1(+) = table2.clo2表示返回等值连接记录和table2中不满足条件的记录。

Ø        +号位于显示较少行的一端。只适用与列,不能和ORIN操作符一起使用。

Ø        示例:表s中的字段sf取值是表t中字段tf的一个子集。现在需要查看表s中是否有记录不满足该条件。

       SELECT * FROM(

              SELECT s.sf s_sf, t.tf t_sf

              FROM s, t

              WHERE s.sf = t.tf(+)

       )

       WHERE t_sf IS NULL;

5 SQL:1999连接

1)笛卡尔积—CROSS JOIN

       SELECT d.dname, e.ename FROM dept d CROSS JOIN emp e;

2)自然连接—Natural JOIN

       自然连接基于两张表的同名列执行相等连接。

       SELECT d.dname, e.ename FROM dept d NATURAL JOIN emp e;

3USING—选择某相同列进行连接

       SELECT d.dname, e.ename FROM dept d, emp e USING(deptno);

4ON子句连接列名不同时可使用

       SELECT d.dname, e.ename FROM dept d JOIN emp e

              ON e.deptno = d.deptno AND e.deptno = 10;

5LEFTER [OUTER] JOIN--左连接

       SELECT d.dname, e.ename FROM dept d LEFT JOIN emp e

              ON e.deptno = d.deptno AND e.deptno = 10;

6RIGHT [OUTER] JOIN –右连接

       SELECT d.dname, e.ename FROM dept d RIGHT JOIN emp e

              ON e.deptno = d.deptno AND e.deptno = 10;

7FULL [OUTER] JOIN—完全外连接

       SELECT d.dname, e.ename FROM dept d FULL JOIN emp e

              ON e.deptno = d.deptno AND e.deptno = 10;

 

 

第9章            数据分组

1 分组函数

       MAX, MIN, AVG, SUM, COUNT

       VARIANCE  方差STDDEV    标准偏差

2 GROUP BY HAVING

1GROUP BY用于指定分组列,HAVING用于限制分组显示结果。

2GROUP可用于单列和多列分组

       SELECT deptno, job, avg(sal) FROM emp GROUP BY deptno, job;

3HAVING限制分组

       SELECT deptno, job, avg(sal) FROM emp GROUP BY deptno, job

              HAVING avg(sal) < 2500;

4)数据分组需注意

Ø        分组函数只能出现在选择列表、ORDER BY子句、HAVING子句中

Ø        分组函数会忽略NULL

Ø        使用分组函数时,可在函数中指定ALLDISTINCT,默认为ALL

Ø        ORDER BY子句必须在最后面。

Ø        选择列表中的列、表达式必须出现在GROUP BY子句中。

3 ROLLUPCUBE

1GROUP BY中使用ROLLUPCUBE可以生成小计和总计。

Ø        ROLLUP(A, B)先按A,B分组统计,再按A分组统计,最后计算总的统计;

Ø        CUBE操作符会生成AB统计,A统计,B统计,总统计;

Ø        GROUP BY ROLLUP(a, b, c)等价于GROUP BY(a, b, c) GROUP BY(a,b)GROUP(a)GROUP()的并集;

Ø        GROUP BY CUBE(a, b, c)等于所有组合情况的并集;

Ø        示例:

       SELECT deptno, job, avg(sal) FROM emp GROUP BY ROLLUP(deptno, job);

       SELECT deptno, job, avg(sal) FROM emp GROUP BY ROLLUP(deptno, job);

2GROUPING函数

Ø        ROLLUPCUBE中确定统计结果是否使用了某列,返回0 表示使用了,返回1表示没有使用该列。

Ø        SELECT deptno, job, avg(sal), GROUPING(deptno), GROUPING(job)

              FROM emp GROUP BY ROLLUP(deptno, job);

3ROLLUPCUBE中使用复合列

Ø        ROLLUP(a, (b,c))等价于GROUP BY(a,b,c)GROUP BY a, GROUP BY ()的并集;

Ø        CUBE((a,b),c)等价于GROUP BY(a, b, c)GROUP BY(a, b)GROUP BY cGROUP BY()的并集。

4 GROUPING SETS操作符

Ø        GROUPING SETS用于显示多个分组的统计结果

Ø        GROUP BY GROUPING SETS(a, b)等价于GROUP BY aGROUP BY b的并集。

Ø        SELECT deptno, job, avg(sal) FROM emp

              GROUP BY GROUPING SETS(deptno, job);

5 连接分组

Ø        连接分组用于组合不同分组的统计结果。

Ø        GROUP BY子句中指定多个GROUPING SETSCUBEROLLUP可以实现连接分组。

Ø        连接多个GROUPING SETS: GROUPING SETS(a, b), GROUPING SETS(c,d)会定义分组(a,b), (a,d), (b,c), (b,d)

       SELECT deptno, job, mgr, sum(sal) FROM emp

              GROUP BY GROUPING SETS(deptno), GROUPING SETS(job, mgr);

Ø        连接ROLLUP, GROUP BY后接a, ROLLUP(b,c)时,会定义分组(a,b,c)(a,b)(a)

       SELECT deptno, job, mgr, sum(sal) FROM emp

              GROUP BY deptno, ROLLUP(job, mgr);

Ø        连接CUBE: 连接CUBE, GROUP BY后接a, CUBE(b,c)时,会定义分组(a,b,c)(a,b), (a,c)(a)

       SELECT deptno, job, mgr, sum(sal) FROM emp

              GROUP BY deptno, CUBE(job, mgr);

第10章            子查询

1 单行子查询

Ø        返回一行数据的子查询语句。可使用单行比较符(=>=, <=, <, >, <>)。

Ø        SELECT * FROM emp WHERE deptno =

              (SELECT deptno FROM dept WHERE deptname = 'Tech');

2 多行子查询

Ø        多行子查询指返回多行数据的子查询语句。多行子查询可使用IN, ALL, ANY.

3 多列子查询

Ø        多列子查询指返回多列数据的子查询语句。与单列的差不多。

Ø        SELECT * FROM emp WHERE (sal, nvl(comm., -1)) IN

              (SELECT sal, nvl(comm, -1) FROM emp WHERE deptno = 30)

4 相关子查询

Ø        子查询引用到主SQL语句的表列时,执行相关子查询;主SQL语句可以是SELECTUPDATE, DELETE语句;普通子查询只执行一次子查询,相关子查询,每处理一行主SQL语句,都会执行一次相关子查询。

Ø        UPDATE示例,表table_testmonth_id, num两列,表示月份id和数据,现有增加一列sum,表示该月及以前的月份的数据总和。

              ALTER TABLE tab_test add sum NUMBER;

              UPDATE table_test t

                     SET t.sum = (SELECT sum(d.num) FROM table_test d WHERE

                            d.month_id <= t.month_id);

       也可以使用分析函数over直接用查询得到结果:

              SELECT t.month_id, t.num, SUM(t.num) OVER(order by t.month_id)

                     FROM table_test t;

              --得到季度数据

              SELECT t.month_id, t.num, SUM(t.num) OVER(PARTITION by                                TRUNC((t.month_id – 1)/3))    FROM table_test t;

              SELECT t.month_id, t.num, SUM(t.num) OVER(PARTITION by                                TRUNC((t.month_id – 1)/3) ORDER BY t.month_di)

                     FROM table_test t;

Ø        EXISTS操作符用于检测子查询是否存在返回行,有返回行时,条件值为true,否则为false;NOT EXISTS EXISTS相反。

       SELECT ename, sal, deptno FROM emp e WHERE EXISTS

              (SELECT 1 FROMdept WHERE deptno = e.deptno AND loc = 'NEW YORK');

5 DDL中使用子查询

Ø        SELECTDML中使用子查询时,WHERE子句和SET子句不能包含ORDER BY子句,DDL中使用时可以包含。DDL使用子查询如CREATE [TABLE | VIEW | MATERIALIZED VIEW].

       CREATE TABLE new_emp(id, name, sal, job, deptno) AS

              SELECT empno, enmae, sal, job, deptno FROM emp;

       --只复制表结构

       CREATE TABLE new AS SELECT * FROM emp WHERE 1 = 0;

6 FROM中使用子查询

Ø        FROM中子查询被当作视图看待,必须指定别名。

       SELECT ename, job, sal FROM emp,

              (SELECT deptno, avg(sal) avgsal FROM emp GROUP BY deptno) dept

              WHERE emp.deptno = dept.deptno AND sal > dept.avgsal;

7 WITH子句重用子查询

       多次引用相同的查询块,可以使用WITH子句为子查询取名,多次引用。

       WITH

       Dept_sum AS(

              SELECT d.dname, sum(e.sal) total FROM dept d, emp e

              WHERE d.deptno = e.deptno GROUP BY d.dname),

       Dept_avg_sum AS(

              SELECT sum(total)/COUNT(*) avg_num FROM dept_sum)

       SELECT dname, total FROM dept_sum

              WHERE total > (SELECT avg_sum FROM dept_avg_sum);

第11章            PL/SQL基础

1 PL/SQL:PL/SQL的基本程序单元

Ø        PL/SQL块结构

DELCARE

       --定义常量、变量、数据类型、游标

BEGIN

       --PL/SQL语句和SQL语句

EXCEPTION

       --异常处理

END

Ø        PL/SQL块分类

匿名块、命名块、子程序(过程、函数、包)、触发器

²       命名块在块前加<<block_name>>即可

2 数据类型

Ø        标量类型、符合类型、参照类型、LOB类型

Ø        %TYPE可根据表列或其它变量的类型定义新变量

Ø        复合变量包括PL/SQL记录、PL/SQL表、嵌套表、VARRAY

Ø        REF CURSOR用于定义游标变量;REF obj_type用于定义对象指针。

Ø        子类型:已存在数据类型的子集:

       SUBTYPE subtype_name IS base_type [(constraint)] [NOT NULL];

3 代码编写规则

变量:前缀v_

常量:前缀c_

游标:后缀_cursor

例外:前缀e_

PL/SQL表类型:后缀_table_type

PL/SQL记录类型:后缀_record_type

 

第12章            SQL*Plus

1 连接命令

Ø        [CONNECT | CONN] user/passwd@SID

Ø        [DISCONNECT | DISC] user/passwd@SID

Ø        PASSWORD | PASSW

Ø        EXIT | QUIT --退出SQL*Plus

2 编辑命令

       SQL*Plus会缓存SQL语句,编辑命令可以显示、编辑修改SQL缓冲区内容。此处编辑命令大多数不用于PL/SQL Developer

Ø        LIST | L        --列出缓冲区内容

Ø        DEL       --删除当前行内容,可指定起始与结束行号。

Ø        EDIT | ED     --编辑

Ø        RUN | /  --运行缓存区中的SQL.

3 文件操作

Ø        SAVE file [CREATE | APPEND | REPLACE]       --保存缓冲区SQL

Ø        GET file  --加载文件至缓冲区

Ø        START | @   file   --执行sql脚本

Ø        @@       --执行可嵌套脚本的sql脚本。

Ø        EDIT      --编辑缓冲区内容

Ø        SPOOL --保存SQL*Plus屏幕内容至文件

       SPOOL file

              Execute SQL

       SPOOL OFF

4 交互式命令

Ø        &var      --引用替代变量,字符类型需用单引号,只在当前语句有效

Ø        &&var   --&var, SQL*Plus环境中有效

Ø        DEFINE       --定义类型为CHAR的替代变量

       DEFINE title = BOB

Ø        UNDEFINE  --清除替代变量的定义

Ø        ACCEPT –定义CHAR, NUMBER, DATE的替代变量。

       ACCEPT title PROMPT ‘请输入标题:'

       ACCEPT pwd hide     --隐藏用户输入

Ø        PROMPT     --提示信息

Ø        PAUSE  --暂停

Ø        VARIABLE | VAR      --定义绑定变量

       VAR no NUMBER

Ø        PRINT –输出绑定变量结果

5 环境变量

Ø        Showall  --显示环境变量

       Show variable       --显示指定环境变量

       Set variable on|off --设置或进制环境变量

Ø        一些环境变量

       AUTOCOMMIT --是否自动提交DML

       SERVEROUTPUT      --控制服务器输出,dbms_output包需设置此变量为ON

       TERMOUT   --控制SQL脚本的输出,OFF则不会显示结果

       TIME     --SQL提示符是否显示时间

       TIMING       --是否显示SQL语句的执行时间。

 

 

后记

负责向Oracle数据库写数据的家伙竟然从来没有接触过Oracle,这可能是个笑话,然而却是真实存在的。于是就有了这篇笔记。在校期间的数据库课程[2]提供了一个理论上的入门,打下了一定的基础。不得不承认,高等教育的课程设置比较完备,如果真的都学精了,那绝对是人才。可惜我一向都学得半生不熟的。不过这不是问题,用到的时候再学就可以了。文献[1]只能算是Oracle学习之路上的一个开端。看第一遍的时候觉得有些东西没理解,当时明白了,之后又觉得比较模糊。于是决定写一下笔记,整理一下思路。写到一部分的时候,发现自己并不擅长于做笔记,特别是需要耗费比较多的时间。书籍是借过来看的,也许是担心以后参考的时候没有资料查阅,这也是做笔记的一个原因。不过现在没有这个必要了。入门之后直接查阅资料就可以了。OTN(Oracle Technology Network)上的资料非常的丰富。下载之后就可以离线查阅了。

 

 

 

 

 

 

 

 

 

 

 

 

Oracle SQL与PL/SQL学习笔记(-) 


      如果可能,本文将不断的更新。

 

 

 

 

参考文献

[1]  王海亮,张立民,王海风等。精通Oracle 10g SQLPL/SQL[M]. 北京:中国水利水电出版社,2007.

[2]  杨开英。数据库系统概论[M]. 武汉:武汉理工大学出版社,2003.