您的位置:首页 > 数据库

PL/SQL循序渐进全面学习教程

2008-07-22 20:11 423 查看
课程一 PL/SQL 基本查询与排序
本课重点:
1、写SELECT语句进行数据库查询
2、进行数学运算
3、处理空值
4、使用别名ALIASES
5、连接列
6、在SQL PLUS中编辑缓冲,修改SQL SCRIPTS
7、ORDER BY进行排序输出。
8、使用WHERE 字段。
一、写SQL命令:
不区分大小写。
SQL语句用数字分行,在SQL PLUS中被称为缓冲区。
最后以;或 / 结束语句。
也可以用RUN来执行语句
二、举例
例1:
SQL> SELECT dept_id, last_name, manager_id
FROM s_emp;
例2:
SQL> SELECT last_name, salary * 12, commission_pct
FROM s_emp;
对于数值或日期型的字段,可以进行相应的四则运算,优先级与标准的高级语言相同。
SQL> SELECT last_name, salary, 12 * (salary + 100)
FROM s_emp;
三、列的别名ALIASES:
计算的时候特别有用;
紧跟着列名,或在列名与别名之间加“AS”;
如果别名中含有SPACE,特殊字符,或大小写,要用双引号引起。
例:
SQL> SELECT last_name, salary,
12 * (salary + 100) "Annual Salary"
FROM s_emp;
四、连接符号:||
连接不同的列或连接字符串
使结果成为一个有意义的短语:
SQL> SELECT first_name || ’ ’ || last_name
|| ’, ’|| title "Employees"
FROM s_emp;
五、管理NULL值:
SQL> SELECT last_name, title,
salary * NVL(commission_pct,0)/100 COMM
FROM s_emp;
此函数使NULL转化为有意义的一个值,相当于替换NULL。
六、SQL PLUS的基本内容,请参考《SQL PLUS 简单实用精髓篇》
七、ORDER BY 操作:
与其他SQL92标准数据库相似,排序如:
SELECT expr
FROM table
[ORDER BY [ASC|DESC]];
从Oracle7 release 7.0.16开始,ORDER BY 可以用别名。
另:通过位置判断排序:
SQL> SELECT last_name, salary*12
FROM s_emp
ORDER BY 2;
这样就避免了再写一次很长的表达式。
另:多列排序:
SQL> SELECT last name, dept_id, salary
FROM s_emp
ORDER BY dept_id, salary DESC;
八、限制选取行:
SELECT expr
FROM table
[WHERE condition(s)]
[ORDER BY expr];
例1:
SQL> SELECT first_name, last_name, start_date
FROM s_emp
WHERE start_date BETWEEN ’09-may-91’
AND ’17-jun-91’;
例2:
SQL> SELECT last_name
FROM s_emp
WHERE last_name LIKE ’_a%’;  //显示所有第二个字母为 a的last_name
例3:
如果有列为NULL
SQL> SELECT id, name, credit_rating
FROM s_customer
WHERE sales_rep_id IS NULL;
优先级:
Order Evaluated Operator
1 All comparison operators (=, <>, >, >=, <, <=, IN, LIKE, IS NULL, BETWEEN)
2 AND
3 OR
总结:我们今天主要学习了如何进行查询SELECT操作,具体的组合查询与子查询将在以后的课堂中学习,同时希望大家可以工作、学习中多多摸索,实践!

课程二 PL/SQL查询行函数
本课重点:
1、掌握各种在PL/SQL中可用的ROW函数
2、使用这些函数的基本概念
3、SELECT语句中使用函数
4、使用转换函数
注意:以下实例中标点均为英文半角
一、FUNCTION的作用:
进行数据计算,修改独立的数据,处理一组记录的输出,不同日期显示格式,进行数据类型转换
函数分为:单独函数(ROW)和分组函数
注意:可以嵌套、可以在SELECT, WHERE, 和 ORDER BY中出现。
语法:function_name (column|expression, [arg1, arg2,...])
二、字符型函数
1、LOWER 转小写
2、UPPER 转大写
3、INITCAP 首字母大写
4、CONCAT 连接字符,相当于 ||
5、SUBSTR SUBSTR(column|expression,m[,n])
6、LENGTH 返回字符串的长度
7、NVL 转换空值
其中,1、2经常用来排杂,也就是排除插入值的大小写混用的干扰,如:
SQL> SELECT first_name, last_name
FROM s_emp
WHERE UPPER(last_name) = ’PATEL’;
FIRST_NAME LAST_NAME
-------------------- --------------------
Vikram Patel
Radha Patel
三、数学运算函数
1、ROUND
四舍五入:
ROUND(45.923,2) = 45.92
ROUND(45.923,0) = 46
ROUND(45.923,-1) = 50
2、TRUNC
截取函数
TRUNC(45.923,2)= 45.92
TRUNC(45.923)= 45
TRUNC(45.923,-1)= 40
3、MOD 余除
MOD(1600,300)
实例:
SQL> SELECT ROUND(45.923,2), ROUND(45.923,0),
ROUND(45.923,-1)
FROM SYS.DUAL;
四、ORACLE日期格式和日期型函数:
1、默认格式为DD-MON-YY.
2、SYSDATE是一个求系统时间的函数
3、DUAL['dju:el] 是一个伪表,有人称之为空表,但不确切。
SQL> SELECT SYSDATE
FROM SYS.DUAL;
4、日期中应用的算术运算符
例:
SQL> SELECT last_name, (SYSDATE-start_date)/7 WEEKS
FROM s_emp
WHERE dept_id = 43;
DATE+ NUMBER = DATE
DATE-DATE= NUMBER OF DAYS
DATE + (NUMBER/24) = 加1小时
5、函数:
MONTHS_BETWEEN(date1, date2) 月份间隔,可正,可负,也可是小数
ADD_MONTHS(date,n) 加上N个月,这是一个整数,但可以为负
NEXT_DAY(date,‘char’) 如:NEXT_DAY (restock_date,’FRIDAY’),从此日起下个周五。
ROUND(date[,‘fmt’])
TRUNC(date[,‘fmt’])
解释下面的例子:
SQL> SELECT id, start_date,
MONTHS_BETWEEN (SYSDATE,start_date) TENURE,
ADD_MONTHS(start_date,6) REVIEW
FROM s_emp
WHERE MONTHS_BETWEEN (SYSDATE,start_date)<48;
我们看到:MONTHS_BETWEEN (SYSDATE,start_date)<48,说明至今工作未满一年的员工。
LAST_DAY (restock_date) 返回本月的最后一天
SQL> select round(sysdate,'MONTH') from dual
ROUND(SYSD
----------
01-11月-01
round(sysdate,'YEAR') = 01-1月 -02
ROUND 之后的值比基值大的最小符合值,大家可以用更改系统时间的方法测试,以15天为分界线,也是非常形象的四舍五入,而TRUNC恰好相反,是对现有的日期的截取。
五、转换函数:
1、TO_CHAR
使一个数字或日期转换为CHAR
2、TO_NUMBER
把字符转换为NUMBER
3、TO_DATE
字符转换为日期
这几个函数较为简单,但要多多实践,多看复杂的实例。
SQL> SELECT ID,TO_CHAR(date_ordered,’MM/YY’) ORDERED
FROM s_ord
WHERE sales_rep_id = 11;
转换时,要注意正确的缺省格式:
SELECT TO_DATE('03-MAR-92') CORRECT FROM DUAL;//正确
SELECT TO_DATE('031092') CORRECT FROM DUAL;//不正确
SELECT TO_DATE('031095','MMDDYY') ERRORR FROM DUAL
输出 3月10日
SELECT TO_DATE('031095','DDMMYY') ERRORR FROM DUAL
输出 10月3日
4、实例:
select to_char(sysdate,'fmDDSPTH "of" MONTH YYYY AM') TODAYS FROM DUAL;
TODAYS
-------------------------------
SIXTEENTH of 11月 2001 下午
大小写没有什么影响,引号中间的是不参与运算。
实例 :
SELECT ROUND(SALARY*1.25) FROM ONE_TABLE;
意义:涨25%工资后,去除小数位。在现实操作中,很有意义。
5、混合实例:
SQL> SELECT last_name, TO_CHAR(start_date,
'fmDD "of" Month YYYY') HIREDATE
FROM s_emp
WHERE start_date LIKE ’%91’;
LAST_NAME HIREDATE
------------ --------------------
Nagayama 17 of June 1991
Urguhart 18 of January 1991
Havel 27 of February 1991
这里要注意:fmDD和fmDDSPTH之间的区别。
SQL> SELECT id, total, date_ordered
FROM s_ord
WHERE date_ordered =
TO_DATE(’September 7, 1992’,’Month dd, YYYY’);
六、独立的函数嵌套
SQL> SELECT CONCAT(UPPER(last_name),
SUBSTR(title,3)) ”Vice Presidents”
FROM s_emp
WHERE title LIKE ’VP%’;
* 嵌套可以进行到任意深度,从内向外计算。
例:
SQL> SELECT TO_CHAR(NEXT_DAY(ADD_MONTHS
(date_ordered,6), 'FRIDAY'),
'fmDay, Month ddth, YYYY')
"New 6 Month Review"
FROM s_ord
ORDER BY date_ordered;
SQL> SELECT last_name,
NVL(TO_CHAR(manager_id),’No Manager’)
FROM s_emp
WHERE manager_id IS NULL;
对于例子,大家重要的理解,并多做测试,并注意英文版和中文版在日期上的区别。
有些教材上的例子,不要盲目的相信其结果,实践后才有发言权,希望大家能够在学习的过程中不要忽略了用,
多想一想为什么实例要如此设计,在何种情况下应用此实例来解决问题。这样,我们才真正掌握了知识。

课程三 从多个表中提取数据
本课重点:
1、SELECT FROM多个表,使用等连接或非等连接
2、使用外连接OUTER JOIN
3、使用自连接
注意:以下实例中标点均为英文半角
一、连接的概念:
是指一个从多个表中的数据进行的查询。连接一般使用表的主键和外键。
连接类型:等连接、不等连接、外连接、自连接
二、Cartesian product:
指的是当JOIN条件被省略或无效时,所有表的行(交叉)都被SELECT出来的现象。
Cartesian product可以产生大量的记录,除非是你有意如此,否则应该加上某种条件限制。
SQL> SELECT name, last_name
FROM s_dept, s_emp;
300 rows selected. 其中一个表12行,一个表25行。
三、简单连接查询:
SELECT table.column, table.column...
FROM table1, table2
WHERE table1.column1 = table2.column2;
如:
SQL> SELECT s_emp.last_name, s_emp.dept_id,
s_dept.name
FROM s_emp, s_dept
WHERE s_emp.dept_id = s_dept.id;
注意:表前缀的重要性:
SQL> SELECT s_dept.id ”Department ID”,
s_region.id ”Region ID”,
s_region.name ”Region Name”
FROM s_dept, s_region
WHERE s_dept.region_id = s_region.id;
在WHERE段中,如果没有前缀,两个表中都有ID字段,就显得的模棱两可,AMBIGUOUS。
这在实际中应该尽量避免。
WHERE字段中,还可以有其他的连接条件,如在上例中,加上:
INITCAP(s_dept.last_name) = ’Menchu’;
再如:
WHERE s_emp.dept_id = s_dept.id AND s_dept.region_id = s_region.id AND s_emp.commission_pct > 0;
四、表别名ALIAS:
1、使用别名进行多表查询 。
2、仅在这个查询中生效,一旦用了表别名,就不能再用表的原有的名字进行连接。
实例:
SQL> SELECT c.name ”Customer Name”,
c.region_id ”Region ID”,
r.name ”Region Name”
FROM s_customer c, s_region r
WHERE c.region_id = r.id;
别名最多可以30个字符,但当然越少越好。最好也能容易识别。
五、非等连接
非等连接一般用在没有明确的等量关系的两个表;
最简单的说:非等连接就是在连接中没有“=”出现的连接。
SQL> SELECT e.ename, e.job, e.sal, s.grade
FROM emp e, salgrade s
WHERE e.sal BETWEEN s.losal AND s.hisal;
说明:Create a non-equijoin to evaluate an employee’s salary grade. The salary 必须在另一个表中最高和最低之间。
其他操作符<= >= 也可以实现,但是BETWEEN是非常简单实用的。
BETWEEN ....AND是指闭区间的,这点要注意 ,请大家测试。
六、外连接
语法结构:
SELECT table.column, table.column
FROM table1, table2
WHERE table1.column = table2.column(+);
实例:
SQL> SELECT e.last_name, e.id, c.name
FROM s_emp e, s_customer c
WHERE e.id (+) = c.sales_rep_id
ORDER BY e.id;
显示……,即使有的客户没有销售代表。
* 可以理解为有+号的一边出现了NULL,也可以做为合法的条件。
外连接的限制:
1、外连接符只能出现在信息缺少的那边。
2、在条件中,不能用IN或者OR做连接符。
七、自连接
同一个表中使用连接符进行查询;
FROM的后面用同一个表的两个别名。
实例:
SQL> SELECT worker.last_name||’ works for ’||
manager.last_name
FROM s_emp worker, s_emp manager
WHERE worker.manager_id = manager.id;
意味着:一个员工的经理ID匹配了经理的员工号,但这个像绕口令的连接方式并不常用。
以后我们会见到一种子查询:
select last_name from s_emp where salary=(select max(salary) from s_emp)
也可以看作是一种变向的自连接。

课程四 组函数
本课重点:
1、了解可用的组函数
2、说明每个组函数的使用方法
3、使用GROUP BY
4、通过HAVING来限制返回组
注意:以下实例中标点均为英文半角
一、概念:
组函数是指按每组返回结果的函数。
组函数可以出现在SELECT和HAVING 字段中。
GROUP BY把SELECT 的结果集分成几个小组。
HAVING 来限制返回组,对RESULT SET而言。
二、组函数:(#号的函数不做重点)
1、AVG
2、COUNT
3、MAX
4、MIN
5、STDDEV #
6、SUM
7、VARIANCE #
语法:
SELECT column, group_function
FROM table
[WHERE condition]
[GROUP BY group_by_expression]
[HAVING group_condition]
[ORDER BY column];
实例1:一个混合实例,说明所有问题:
SQL> SELECT AVG(salary), MAX(salary), MIN(salary),
SUM(salary)
FROM s_emp
WHERE UPPER(title) LIKE ’SALES%’;
AVG(SALARY) MAX(SALARY) MIN(SALARY) SUM(SALARY)
----------- ----------- ----------- -----------
1476 1525 1400 7380
说明:很多函数,我们在讲函数的已经向大家介绍过,但在此为何叫分组函数呢,主要是因为它们可以与GROUP BY来形成对不同组的计算,相当于在很多值中进行挑选。
* MIN MAX函数可以接任何数据类型。
如果是MIN(last_name), MAX(last_name),返回的是什么呢?
千万记住,不是指LAST_NAME的长度,而是指在FIRST字母的前后顺序,第一个相同,然后比较第二个,如:xdopt > cssingkdkdk > adopt > acccc
实例2:
SQL> SELECT COUNT(commission_pct)
FROM s_emp
WHERE dept_id = 31;
返回所有非空行个数
三、GROUP BY的应用:
先看一个简单实例:
SQL> SELECT credit_rating, COUNT(*) ”# Cust”
FROM s_customer
GROUP BY credit_rating;
注意这里别名的应用,复习一下从前的课程,加了引号后,就可以用特殊字符,但也仅有三个:#$_,什么对象的名字都如此。当然空格也是可以的。
复杂实例:
SQL> SELECT title, SUM(salary) PAYROLL
FROM s_emp
WHERE title NOT LIKE ’VP%’
GROUP BY title
ORDER BY SUM(salary);
这里要注意一下几个CLAUSE的先后次序。
WHERE在这里主要是做参与分组的记录的限制。
* 另外,如果要选取出来一个不加组函数的列,如上面的TITLE,就要把这个列GROUP BY!否则要出错的!信息为:ERROR at line 1:
ORA-00937: not a single-group group function
理论很简单,如果不GROUP BY TITLE,显示哪一个呢?这个在试题中经常出现。
结论:不加分组函数修饰的列必定要出现在GROUP BY 里。
错误实例:
SQL> SELECT dept_id, AVG(salary)
FROM s_emp
WHERE AVG(salary) > 2000
GROUP BY dept_id;
WHERE AVG(salary) > 2000
* ERROR at line 3:
ORA-00934: group function is not allowed here
应在GROUP BY 后面加上HAVING AVG(salary) > 2000;
因为是用来限制组的返回。
多级分组实例:
SQL> SELECT dept_id, title, COUNT(*)
FROM s_emp
GROUP BY dept_id, title;
就是先按照DEPT_ID分组,当DEPT_ID相同的时候,再按TITLE分组,而COUNT(*)以合成的组计数。
顺序对结果有决定性的影响。
总结:本课我们主要学习了分组函数的使用及如何进行分组查询,我们可以想像一下,SQL SERVER中有COMPUTE BY,来进行分组总数的计算,但在ORACLE中是没有的。大家可以建立一个有多个列,多个重复值的表,然后进行各种分组的演示,用得多了,自然明了。

课程五 子查询
本课重点:
1、在条件未知的情况下采用嵌套子查询
2、用子查询做数据处理
3、子查询排序
注意:以下实例中标点均为英文半角
一、概述:
子查询是一种SELECT句式中的高级特性,就是一个SELECT语句作为另一个语句的一个段。我们可以利用子查询来在WHERE字段中引用另一个查询来攻取值以补充其无法事先预知的子结果。
子查询可以用在WHERE子句,HAING子句,SELECT或DELETE语句中的FROM 子句。
注意:
1、子查询必须在一对圆括号里。
2、比较符号:>, =, 或者 IN.
3、子查询必须出现在操作符的右边
4、子查询不能出现在ORDER BY里
二、子查询的执行过程:
NESTED QUERY
SQL> SELECT dept_id
FROM s_emp
WHERE UPPER(last_name)='BIRI';
MAIN QUERY
SQL> SELECT last_name, title
FROM s_emp
WHERE dept_id =
这里 ,每个查询只运行一次。当然,子查询要首先被执行,大家设想一下,如果子查询中有一个以上的人的LASTNAME为BIRI,会如何?-----会出错,因为不能用=来连接。
ORA-1427: single-row subquery returns more than one row
以上的查询也被称为单行子查询。
DELECT子查询实例:
delete from new_table where cata_time > to_date('19990901','yyyymmdd') and pro_name=(
select pro_name from new_product where pro_addr in ('bj','sh'))
三、子查询中的GROUP 函数的应用
实例 1:
SQL> SELECT last_name, title, salary
FROM s_emp
WHERE salary <
(SELECT AVG(salary)
FROM s_emp);
实例2:
选择出工资最高的员工的家庭住址:
select emp_addr from employees where salary =
(select max(salary) from employees);
这是一个简单实用的例子,可以衍生出很多情况,在实际应用经常出现,请大家多多思考。
实例3:
SQL> SELECT dept_id, AVG(salary)
FROM s_emp
GROUP BY dept_id
HAVING AVG(salary) >
(SELECT AVG(salary)
FROM s_emp
WHERE dept_id = 32);
子查询被多次执行,因为它出现在HAVING 子句中。
SQL> SELECT title, AVG(salary)
FROM s_emp
GROUP BY title
HAVING AVG(salary) =
(SELECT MIN(AVG(salary))
FROM s_emp
GROUP BY title);
对子查询,我们了解这么多在理论上已经覆盖了所有的知识点,对于UPDATE 和DELETE的子查询,不作为重点,但也要练习掌握。今天到这,谢谢大家。

课程六 运行时应用变量
本课重点:
1、创建一个SELECT语句,提示USER在运行时先对变量赋值。
2、自动定义一系列变量,在SELECT运行时进行提取。
3、在SQL PLUS中用ACCEPT定义变量
注意:以下实例中标点均为英文半角
一、概述:
变量可以在运行时应用,变量可以出现在WHERE 字段,文本串,列名,表名等。
1、我们这里的运行时,指的是在SQL PLUS中运行。
2、ACCEPT :读取用户输入的值并赋值给变量
3、DEFINE:创建并赋值给一个变量
4、在做REPORT时经常使用,比如对某个部门的销售信息进行统计,部门名称可以以变量代替。
SQL PLUS不支持对输入数据的有效性检查,因此提示要简单且不模棱两可。
二、应用实例:
1、
SQL> SELECT id, last_name, salary
FROM s_emp
WHERE dept_id = &department_number;
2、可以在赋值前后进行比较:
SET VERIFY ON
.....
1* select * from emp where lastname='&last_name'
输入 last_name 的值: adopt
原值1: select * from emp where lastname='&last_name'
新值1: select * from emp where lastname='adopt'
——如果在原语句中没有单引号,那么在输入值的时候要手工加上单引号。一般字符和日期型要在语句中加上单引号。
SET VERIFY OFF 之后,原值和新值这两句消失。这在ORACLE8I中是默认为ON。
3、子句为变量:WHERE &condition; 要注意引号
三、DEFINE和ACCEPT的应用:
1、SET ECHO OFF //使内容不 显示在用户界面
ACCEPT p_dname PROMPT ’Provide the department name: ’
SELECT d.name, r.id, r.name ”REGION NAME”
FROM s_dept d, s_region r
WHERE d.region_id = r.id
AND UPPER(d.name) LIKE UPPER(’%&p_dname%’)
/
SET ECHO ON
存为文件:l7prompt.SQL
SQL> START l7prompt
Provide the department name: sales
2、
SQL> DEFINE dname = sales
SQL> DEFINE dname
DEFINE dname = ”sales” (CHAR)
SQL> SELECT name
FROM s_dept
WHERE lower(name) = ’&dname’;
可以正常执行了。
SQL> DEFINE dname 主要是显示当前的变量是否赋值,值是什么。当然,我们可以用UNDEFINEGO 来使变量恢复初始,不然它会一直保持下去。
3、如果变量在SQL SCRIPT文件中确定 :可以SQL> START l7param President 来赋值。
总结:本课主要针对较古老的SQLPLUS方法,在REPORT和结果集生成方面使用变量,达到方便操作,动态修改的目的。

课程七 其他数据库对象
SEQUENCE创建实例:
SQL> CREATE SEQUENCE s_dept_id
INCREMENT BY 1
START WITH 51
MAXVALUE 9999999
NOCACHE
NOCYCLE;
Sequence created.
1、NEXTVAL和CURRVAL的用法
只有在INSERT 中,才可以作为子查询出现。
以下几个方面不可用子查询:
SELECT 子句OF A VIEW
有DISTINCT的出现的SELECT。
有GROUP BY,HAVING,ORDER BY的SELECT 子句。
SELECT 或DELETE,UPDATE 中的子查询。
DEFAULT选项中不能用。
2、编辑SEQUENCE
只有OWNER或有ALTER权限的用户才能修改SEQUENCE
未来的NUMBER受修改的影响。
不能修改START WITH,如果变,则要RE-CREATE。
修改会受到某些有效性检验的限制,如MAXVALUE
3、删除:
DROP SEQUENCE sequence;
ORACLE对象之INDEX
一、INDEX概述:
ORACLE的一种数据对象,用POINTER来加速查询行。通过快速路径存取方法定位数据并减少I/O。 INDEX独立于表。INDEX由ORACLE SERVER来使用和保持。
二、索引如何建立?
1、自动:通过PRIMARY KEY和UNIQUE KEY约束来建立。
2、用户手工建立非唯一性索引。
三、创建方法:
语法:
CREATE INDEX index
ON table (column[, column]...);
何时建立INDEX:
此列经常被放到WHERE字段或JOIN来作条件查询。
此列含有大量的数据。
此列含有大量的空值。
两个或几个列经常同时放到WHERE字段进行组合查询
表很大而且只有少于2-4% 的ROW可能被查询的时候。
以下情况不要建立索引:
表很小;
表被更新频繁。
四、查看已经存在的索引:
1、USER_INDEXES可以查询索引名和类型。
2、USER_IND_COLUMNS包含索引名、表名、列名。
实例:
SQL> SELECT ic.index_name, ic.column_name,
ic.column_position col_pos, ix.uniqueness
FROM user_indexes ix, user_ind_columns ic
WHERE ic.index_name = ix.index_name
AND ic.table_name = ’S_EMP’;
五、删除索引:
DROP INDEX index;
SYNONYMS 同义词
语法:
CREATE [PUBLIC] SYNONYM synonym for object;
注意:此对象不能包含在一个包里;
一个私有的同义词不能与同一USER的其他对象重名。
DROP SYNONYM D_SUM;

课程八 用户访问控制
本课重点:
1、创建用户
2、创建角色来进行安全设置
3、使用GRANT或REVOKE 来控制权限
注意:以下实例中标点均为英文半角
一、概述:
ORACLE通过用户名和密码进行权限控制。
数据库安全:系统安全和数据安全
系统权限:使用户可以访问数据库
对象权限:操纵数据库中的对象
SCHEMA:各种对象的集合
二、系统权限:
1、超过80个权限可用。
2、DBA有最高的系统权限:
CREATE NEW USER
REMOVE USERS
REMOVE ANY TABLE
BACKUP ANY TABLE
三、创建用户
1、CREATE USER user IDENTIFIED BY password;
2、系统权限:
CREATE SESSION Connect to the database.
CREATE TABLE Create tables in the user’s schema.
CREATE SEQUENCE Create a sequence in the user’s schema.
CREATE VIEW Create a view in the user’s schema.
CREATE PROCEDURE Create a stored procedure, function, or package in the user’s schema.
3、授权用户系统权限:
GRANT privilege [, privilege...] TO user [, user...];
GRANT CREATE TABLE TO SCOTT;
四、角色的使用
1、概念:角色是一组权限的命名,可以授予给用户。这样就如同给了某个用户一个权限包。
2、创建、授予给角色:
CREATE ROLE MANAGER;
GRANT CREATE TABLE,CREATE VIEW TO MANAGER;
GRANT MANAGER TO CLARK
五、修改密码:
ALTER USER user IDENTIFIED BY password;
六、对象权限:
1、语句:
GRANT {object_priv(, object_priv...)|ALL}[(columns)]
ON object
TO {user[, user...]|role|PUBLIC}
[WITH GRANT OPTION];
2、实例:
最简单:
SQL> GRANT select
ON s_emp
TO sue, rich;
稍复杂:
SQL> GRANT update (name, region_id)
ON s_dept
TO scott, manager;
SQL> GRANT select, insert
ON s_dept
TO scott
WITH GRANT OPTION;
课程九 声明变量
本课重点:
1、了解基本的PLSQL块和区域
2、描述变量在PLSQL中的重要性
3、区别PLSQL与非PLSQL变量
4、声明变量
5、执行PLSQL块
注意:以下实例中标点均为英文半角
一、概述:
1、PLSQL 块结构:
DECLARE——可选
变量声明定义
BEGIN——必选
SQL和PLSQL语句
EXCEPTION——可选
错误处理
END——必选
二、实例:
declare
vjob varchar(9);
v_count number:=0;
vtotal date:=sysdate +7;
c_tax constant number(3,2):=8.25;
v_valid boolean not null:=true;
begin
select sysdate into vtotal from dual;
end;
/
上例中,如果没有这个SELECT语句,会如何?
出错,说明必须有STATEMENTS
如果: select sysdate from dual into vtotal;
同样,也不行。而且变量与赋值的类型要匹配。
三、%TYPE的属性
声明一个变量使之与数据库某个列的定义相同或与另一个已经定义过的变量相同
所以%TYPE要作为列名的后缀:如:
v_last_name s_emp.last_name%TYPE;
v_first_name s_emp.first_name%TYPE;
——这样做的好处是我们不必去知晓此列的类型与定义
或:
v_balance NUMBER(7,2);
v_minimum_balance v_balance%TYPE := 10;
四、声明一个布尔类型的变量
1、只有TRUE、FALSE、NULL可以赋值给BOOLEAN变量
2、此变量可以接逻辑运算符NOT、AND、OR。
3、变量只能产生TRUE、FALSE、NULL。
实例:
VSAL1:=50000;
VSQL2:=60000;
VCOMMSAL BOOLEAN:=(VSAL1——其实是把TRUE赋值给此变量。
五、LOB类型的变量
共有CLOB、BLOB、BFILE、NCLOB几种,这里不做为重点。
六、使用HOST VARIABLES
SQL> variable n number
SQL> print n
:n=v_sal /12;
:n这个加了:前缀的变量不是PLSQL变量,而是HOST。
七、以下几个PLSQL声明变量,哪个不合法?
A、DECLARE V_ID NUMBER(4);
B、DECLARE V_X,V_Y,V_Z VARCHAR2(9);
C、DECLARE V_BIRTH DATE NOT NULL;
D、DECLARE V_IN_STOCK BOOLEAN:=1;
E、DECLARE TYPE NAME_TAB IS TABLE OF VARCHAR2(20)
INDEX BY BINARY_INTEGER;
DEPT_NAME NAME_TAB;
上面的习题我会在下章给出答案,这也正是声明变量的规则和难点。

课程十 写执行语句
本课重点:
1、了解PLSQL执行区间的重要性
2、写执行语句
3、描述嵌套块的规则
4、执行且测试PLSQL块
5、使用代码惯例
注意:以下实例中标点均为英文半角
一、PLSQL 块的语法规则:
1、语句可以跨跃几行。
2、词汇单元可以包括:分隔符、标识符、文字、和注释内容。
3、分隔符:
+-*/=<>||....
4、标识符:
最多30个字符,不能有保留字除非用双引号引起。
字母开头,不与列同名。
5、文字串:如 V_ENAME:='FANCY';要用单引号括起来。
数值型可以用简单记数和科学记数法。
6、注释内容:单行时用-- 多行用/* */ ,与C很相似
二、SQL函数在PL/SQL的使用:
1、可用的:
单行数值型、字符型和转换型,日期型。
2、不可用的:
最大、最小、DECODE、分组函数。
实例:
BEGIN
SELECT TO_CHAR(HIREDATE,'MON,DD,YYYY') FROM EMP;
END;
V_comment:=user||':'||sysdate; -- 会编译出错
V_comment:=user||':'||to_char(sysdate); --正确
如果有可能,PLSQL都会进行数据一致性的转换,但ORACLE推荐你应该进行显示的转换,因为这样会提高性能。
三、嵌套块和变量作用区域
1、执行语句允许嵌套时嵌套。
2、嵌套块可以看作正常的语句块。
3、错误处理模块可以包括一个嵌套块
4、exponential指数 逻辑、算数、连接、小括号
5、看正面实例:
declare
vjob varchar(9);
v_count number:=0;
vtotal date:=sysdate +7;
c_tax constant number(3,2):=8.25;
v_valid boolean not null:=true;
ttt vtotal%type;
begin
--select sysdate into vtotal from dual;--体会有无此句与结果的影响
dbms_output.put_line (vtotal);
end;
/
注意:在执行块之前,要在SQL PLUS中执行:SET SERVEROUTPUT ON
四、以实例来说明函数的参数声明作用域
declare
v_weight number(3):=600;
v_message varchar2(255):='product10000';
begin
declare
--sub-block
v_weight number(3):=1;
v_message varchar2(255):='pro300';
begin
v_weight:=v_weight +1;
end;
v_weight:=v_weight +1;
v_message:=v_message || 'my name';
end;
/
子块中的V_WEIGHT值为 2
我们可以在子块中加入:dbms_output.put_line('subblock value is '||v_weight);
在主体中加入:dbms_output.put_line('main value is '||v_weight);
我们发现MAINBLOCK中V_WEIGHT为 601
改动:
1、在主块的声明中加 v_date date default sysdate;
在子块中加入:dbms_output.put_line('subblock date value is '||v_date);
执行结果:subblock date value is 22-11月-01
* 说明:主块中的变量,如果子块中没有同名变量声明,则继承主块中的声明和初始化值;
2、在子块中加入:v_sub char(9);
dbms_output.put_line('subblock char value is '||v_sub);
此时正常输出。
在主块中加入:dbms_output.put_line('main char value is '||v_sub);
输出:ORA-06550: 第 21 行, 第 45 列:
PLS-00201: 必须说明标识符 'V_SUB'
说明:
子块中声明的变量主块中并不知晓,因此出错。
了解了此实例,一切情况的变量的值的走向就都明了了。

课程十一 与ORACLE SERVER交互
本课重点:
1、在PLSQL中成功的写SELECT语句
2、动态声明PLSQL变量类型与SIZE
3、在PLSQL中写DML语句
4、在PLSQL中控制事务
5、确定DML操作的结果
注意:以下实例中标点均为英文半角
一、PLSQL中的SQL语句:
SELECT、DML、COMMIT、ROLLBACK、SAVEPOINT、CURSOR
特殊强调:PLSQL不支持DCL,不要问为什么。(DBMS_SQL package allows you to issue DDL and DCL statements.)
二、SELECT
SELECT select_list
INTO variable_name | record_name
FROM table
WHERE condition;
例:
SQL> r
declare
v_deptno number(2);
v_loc varchar2(15);
begin
select deptno,loc
into v_deptno,v_loc
from dept
where dname='SALES';
DBMS_OUTPUT.PUT_LINE (V_deptno ||' and '||v_loc);
* end;
and CHICAGO
选取字段与变量个数和类型要一致。声明的变量一定要在SIZE上大于返回的赋值,否则提示缓冲区溢出。
如果SELECT语句没有返回值:
ORA-01403: 未找到数据
ORA-06512: 在line 5
如果有多个值返回:
ORA-01422: 实际返回的行数超出请求的行数
这些我们到了错误处理时会逐一讲解。
例:
上面的例子可以改为:
declare
v_deptno dept.deptno%type;
v_loc dept.loc%type;
begin
select deptno,loc
into v_deptno,v_loc
from dept
where dname='SALES';
DBMS_OUTPUT.PUT_LINE (V_deptno ||' and '||v_loc);
end;
/
这样,可以在未知其他字段大小和类型的时候定义变量,提高兼容性。
三、DML 操作:
1、实例:
declare
v_empno emp.empno%type;
begin
select max(empno)
into v_empno
from emp;
v_empno:=v_empno+1;
insert into emp(empno,ename,job,deptno)
values(v_empno,'asdfasdf','ddddd',10);
end;
/
这样也可以实现如SEQUENCE一样的编号唯一递增。
2、更新和删除:
这个较为简单:
DECLARE
V_DEPTNO EMP.DEPtno%type :=10;
begin
delete from emp
where deptno=v_deptno;
end;
/
大家多多实践即可掌握。
PL/SQL首先检查一个标识符是否是一个数据库的列名,如果不是,再假定它是一个PLSQL的标识符。所以如果一个PLSQL的变量名为ID,列中也有个ID,如:
SELECT date_ordered, date_shipped
INTO date_ordered, date_shipped
FROM s_ord
WHERE id = id;
就会返回TOO MANY ROWS,这是要尽量避免的。
四、SQL CURSOR
游标是一个独立SQL工作区,有两种性质的游标:
隐式游标:当PARSE 和EXECUTE 时使用隐式游标。
显式游标:是由程序员显式声明的。
游标的属性:
SQL%ROWCOUNT:一个整数值,最近SQL语句影响的行数。
SQL%FOUND BOOLEAN属性,如果为TRUE,说明最近的SQL STATEMENT有返回值。
SQL%NOTFOUND 与SQL%FOUND相反
SQL%ISOPEN 在隐式游标中经常是FALSE,因为执行后立即自动关闭了。
SQL> variable row_de number
SQL> r
declare
v_deptno number:=10;
begin
delete from emp where
deptno=v_deptno;
:row_de:=sql%rowcount;
* end;
PL/SQL 过程已成功完成。
SQL> print row_de ——这是一个SQL PLUS变量
ROW_DE
----------
4
这时其实并没有真正的删除,而是需要 COMMIT或ROLLBACK,来完成事务。

课程十二 编写控制结构语句
本课重点:
1、结构控制的的用途和类型
2、IF 结构
3、构造和标识不同的循环
4、使用逻辑表
5、控制流和嵌套
注意:以下实例中标点均为英文半角
一、控制执行流
可以是分支和循环:
IF THEN END IF
IF condition THEN
statements;
[ELSIF condition THEN
statements;]
[ELSE
statements;]
END IF;
例子:
IF V_ENAME='OSBORNE' THEN
V_MGR:=22;
END IF;
这里我们可以注意,PLSQL和C语言或JAVA在条件上的不同,=代表关系运算,而:=代表赋值。
看一个函数:
create    FUNCTION calc_val
(v_start IN NUMBER)
RETURN NUMBER
IS
BEGIN
IF v_start > 100 THEN
RETURN (2 * v_start);
ELSIF v_start >= 50 THEN
RETURN (.5 * v_start);
ELSE
RETURN (.1 * v_start);
END IF;
END calc_val;
现在,虽然我们尚未讲解CREATE 函数或过程,但可以看到IF 条件在其中的作用。
二、注意LOGIC TABLE中的逻辑对应关系
1、NOT、AND、OR
2、任何表达式中含有空值结果都为 NULL
3、连接字符串中含有空值会把NULL作为 EMPTY STRING
declare
v_deptno dept.deptno%type;
v_loc
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息