1. 软件工程师培训系列教材
2. PL/SQL数据库编程
3. 第一章
1.PL/SQL简介
2. PL/SQL程序结构
3. 变量与数据类型
4. PL/SQL控制语句
5. PL/SQL游标
6. 异常捕获
7. 子程序
1. 过程
2. 函数
8. 包
9. 触发器
4. Oracle▲应用编程方法概览
Pro*C/C++
PL/SQL
ODBC
OCI
SQLJ
JDBC
XSQL▲
注:▲ 甲骨文公司,世界第二大软件公司,主营数据库产品,并提供基于数据库的全面的企业级应用方案。
▲ eXtension Structure Query Language扩展结构化查询语言,加强的SQL子集,Oracle公司的新技术。
5. PL/SQL
PL/SQL(Procedural Language/SQL)是在标准SQL的基础上增加了过程化处理的语言
Oracle客户端工具访问Oracle服务器的操作语言
Oracle对SQL的扩充
BEGIN
IF TO_CHAR(SYSDATE, 'DAY')='Monday' THEN
pay_for_hamburgers;
ELSE
borrow_hamburger_money;
END IF;
END;
6. PL/SQL
结构化模块化编程
良好的可移植性
良好的可维护性
提升系统性能
不便于向异构数据库移植应用程序
7. SQL
第四代语言
做什么,不管怎么做
缺少过程与控制语句
无算法描述能力
8. PL/SQL
Procedural Language/SQL
扩展
-变量和类型
-控制结构
-过程与函数
-对象类型与方法
BEGIN
IF TO_CHAR(SYSDATE, 'DAY')='Monday' THEN
pay_for_hamburgers;
ELSE
borrow_hamburger_money;
END IF;
END;
9. 第二章
1.PL/SQL简介
2. PL/SQL程序结构
3. 变量与数据类型
4. PL/SQL控制语句
5. PL/SQL游标
6. 异常捕获
7. 子程序
1. 过程
2. 函数
8. 包
9. 触发器
10. PL/SQL程序结构
PL/SQL块
-申明部分, DECLARE
-执行部分, BEGIN
-异常处理, EXCEPTION
DECLARE
v_StudentID NUMBER(5):=1000;
v_FirstName VARCHAR(20);
BEGIN
SELECT first_name
INTO v_FirstName
FROM students
WHERE id=v_StudentID;
EXCEPTION
WHEN NO_DATA_FOUND THEN
INSERT INTO log_table(info)
VALUES('Student 1000 does not exist!');
END;
11. PL/SQL开发环境
SqlPlus▲工具
GUI开发工具
-SQL游览家
-SQL程序员
……
相关信息
http://www.oracle.com
http://gwynne.cs.ualberta.ca/~oracle/817doc/index.htm
注:▲ Oracle公司的SQL工具,也可以用它来操作Oracle数据库。
12. PL/SQL字符集
字母:A-Z, a-z
数字:0-9
空白:Tab,空格,回车
符号:+-*/<>=();:'@"%||&--/**/
PL/SQL对大小写不敏感
13. 标识符
用来给对象命名
-变量、游标、类型、子程序
命名规则
-字母开头
-后跟任意的非空格字符、数字、货币符号、下划线或#
-最大长度为30个字符
标识符的例子
x, First Name, v_StudentID, x+y, TempVar, _tmp_, v1, v2_,
1_var, s#, v$3, This_is_a_really_long_identifier
14. 变量声明
语法
变量名 类型 [常数] [非空] [:=值];
例子
DECLARE
v_Desc VARCHAR2(50);
v_Num NUMBER:=45;
v_Count BINARY_INTEGER:=0;
PL/SQL规定没有初始化的变量为NULL
-NULL:未定义
15. 第三章
1.PL/SQL简介
2. PL/SQL程序结构
3. 变量与数据类型
4. PL/SQL控制语句
5. PL/SQL游标
6. 异常捕获
7. 子程序
1. 过程
2. 函数
8. 包
9. 触发器
16. 数据类型
标量型
-数字型、字符型、布尔型、日期型
组合型
-RECORD, TABLE, VARRAY
参考型
-REF CURSOR, REF object_type
LOB(大对象)
-BFILE 是二进制,存储在数据库外面的
-BLOB 是二进制
-CLOB 是单字节字符数据
-NCLOB 是多字节字符数据
17. 标量类型
数字类型
-BINARY_INTEGER, DEC, FLOAT, REAL...
-NUMBER
-NUMBER(3)
-NUMBER(4,3)
-How about NUMBER(4,6)
字符型
-CHAR, VARCHAR, VARCHAR2, STRING...
-LONG
布尔型(BOOLEAN)
日期型(DATE)
18. %TYPE
变量具有与数据库的表中某一字段相同的类型
DECLARE
v_FirstName VARCHAR2(20);
DECLARE
v_FirstName students.first_name%TYPE;
19. 记录类型
TYPE 记录名 IS RECORD(
域1 类型1 [非空] [:=表达式1]
域2 类型2 [非空] [:=表达式2]
...
域n 类型n [非空] [:=表达式n]
如果一个字段限定NOT NULL,那么它必须拥有一个初始值
所有没有初始化的字段都会初始化为NULL
20. RECORD类型的使用
DECLARE
TYPE t_Rec IS RECORD(
student_id NUMBER(4),
first_name VARCHAR2(20):='Scott',
last_name VARCHAR2(20),
major BINARY_INTEGER);
v_Stu t_Rec;
同类型的RECORD变量可以相互赋值
按RECORD变量的字段赋值(记录名.域名)
21. %ROWTYPE
%ROWTYPE返回一个基于数据库表定义的类型
DECLARE
v_StuRec Student%ROWTYPE;
...
v_StuRec.student_id := 1234;
v_StuRec.first_name := 'Bush';
...
%ROwtype和record的区别是什么?
22. TABLE类型
TYPE 表类型 IS TABLE OF 类型 INDEX BY BINARY_INTEGER;
TABLE类型与map<int, _T>类似
表中元素的类型可以是复合类型
行的数目的限制由BINARY_INTEGER的范围决定
Key没有必要是顺序的
当数据被插入表中时,表所需的空间就被分配了
23. TABLE类型的例子
DECLARE
TYPE t_StuTable IS TABLE OF Student%ROWTYPE INDEX BY BINARY_INTEGER;
v_Student t_StuTable;
BEGIN
SELECT *
INTO v_Student(1001)
FROM Student
WHERE id = 1001;
END;
24. 变量的作用域与可见性
DECLARE
v_Num NUMBER(3, 2);
BEGIN
v_Num := 123.45;
DECLARE
v_Ch VARCHAR2(10);
BEGIN
v_Num := 321.45;
v_Ch := 'Hello';
...
END;
...
END;
25. 第四章
1.PL/SQL简介
2. PL/SQL程序结构
3. 变量与数据类型
4. PL/SQL控制语句
5. PL/SQL游标
6. 异常捕获
7. 子程序
1. 过程
2. 函数
8. 包
9. 触发器
26. PL/SQL控制语句
条件语句
循环语句
GOTO语句
注:▲ 在PL/SQL中,--为单行注释,/**/为多行注释。
27. 条件语句
IF THEN ELSE END IF
IF 布尔表达式1 THEN
...
ELSIF 布尔表达式2 THEN
...
ELSE
...
END IF;
条件为NULL与FALSE相同
28. 循环语句1
简单循环
LOOP
...
IF 布尔表达式 THEN
EXIT;
END IF;
END LOOP;
29. 循环语句2
WHILE循环
WHILE 布尔表达式 LOOP
...
END LOOP;
30. 循环语句3
FOR循环
FOR 循环计数 IN [反向的] 下限..上限 LOOP
...
END LOOP;
31. GOTO语句
GOTO 标签名;
只能由内部的语句块跳往外部块
设置标签
<<标签名>>
可以为循环设置标签
...
<<l_b1>>
FOR v_index IN 1..50 LOOP
...
IF v_index > 40 THEN
EXIT l_b1;
END IF;
END LOOP l_b1;
32. NULL语句
可以在语句块中加空语句
用于补充语句的完整性
IF v_idx > 40 THEN
...
ELSE
NULL;
END IF;
33. SQL中的PL/SQL 1
数据操纵语言
SELECT, INSERT, DELETE, SET TRANSACTION, EXPLAIN PLAN
数据定义语言
DROP, CREATE, ALTER, GRANT, REVOKE
事务控制
COMMIT, ROLLBACK, SAVEPOINT
会话控制
ALERT SESSION, SET ROLE
系统控制
ALERT SYSTEM
ESQL
CONNECT, DECLARE CURSOR, ALLOCATE
34. SQL中的PL/SQL 2
只有DML SQL可以直接在PL/SQL中使用
使用Oracle内置的DBMS_SQL包,可以使用动态SQL语句
动态SQL语句是在运行时生成一个SQL的串,将该串提交给DBMS_SQL包来执行
35. 内置的SQL函数
字符函数
CHR, CONCAT, INITCAP, LOWER, LPAD, LTRIM, RTRIM, REPLACE,
RPAD, SUBSTR, SUBSTRB, TRANSLATE UPPER, INSTR, ASCII,LENGTH...
数字函数
ABS, ACOS, ASIN, CEIL, EXP, FLOOR, LOG, MOD, POWER, ROUND...
日期函数
ADD_MONTHS, LAST_DAY, MONTHS_BETWEEN, NEW_TIME, NEXT_DAY, ROUND, SYSDATE, TRUNC...
转换函数
CHARTOROWID, CONVERT,HEXTORAW, RAWTOHEX, ROWIDTOCHAR, TO_CHAR, TO_DATE, COUNT...
36. 第五章
1.PL/SQL简介
2. PL/SQL程序结构
3. 变量与数据类型
4. PL/SQL控制语句
5. PL/SQL游标
6. 异常捕获
7. 子程序
1. 过程
2. 函数
8. 包
9. 触发器
37. 游标
游标用于提取多行数据集
游标的使用
-声明游标
-为查询打开游标
-将结果提取出来,存入PL/SQL变量中
-关闭游标
38. 声明游标
DECLARE CURSOR 游标名 IS 选择声明
如果在选择声明中使用了PL/SQL,变量的声明必须放在游标前面
v_major students.major%TYPE;
DECLARE
CURSOR c_student IS
SELECT first_name, last_name
FROM students
WHERE major = v_major;
变量名与列名一致但不同
39. 打开游标
OPEN 游标名
若选择声明已“等待更新”则加锁。
40. 从游标取
FETCH的两种形式
-FETCH 游标名 INTO 变量1, 变量2,...;
-FETCH 游标名 INTO 变量记录
41. 关闭游标
CLOSE 游标名;
游标使用后应该关闭
-FETCH关闭后的游标是非法的
-关闭一个关闭了的游标也是非法的
42. 游标的属性
%FOUND
%NOTFOUND
%ISOPEN
%ROWCOUNT
43. 游标的FETCH循环
LOOP
FETCH 游标 INTO...
EXIT WHEN 游标%NOTFOUND;
END LOOP;
WHILE 游标%FOUND LOOP
44. 游标的例子
Mycursor:
print name and id from student where age < 30
For_cursor:
Print dept_id, user_id, last_name, first_name from s_emp
where dept_id < 40
45. 带参数的游标
CURSOR可以带参数
DECLARE
CURSOR c_student(p_major students.major%TYPE)
SELECT *
FROM students
WHERE major = p_major;
BEGIN
OPEN c_student(101);
...
46. 第六章
1.PL/SQL简介
2. PL/SQL程序结构
3. 变量与数据类型
4. PL/SQL控制语句
5. PL/SQL游标
6. 异常捕获
7. 子程序
1. 过程
2. 函数
8. 包
9. 触发器
47. 异常
PL/SQL错误
-编译时
-运行时
运行时的出错处理
-EXCEPTION
48. 异常处理块
DECLARE
...
BEGIN
...
EXCEPTION
WHEN OTHERS THEN
handler_error(...);
END;
49. 用户自定义的异常
DECLARE
e_TooManyStudents EXCEPTION;
BEGIN
...
RAISE e_TooManyStudents;
...
EXCEPTION
WHEN e_TooManyStudents THEN
...
END;
50. 预定义的ORACLE异常
ORA-0001
-DUP_VAL_ON_INDEX
ORA-0051
-TIMEOUT_ON_RESOURCE
ORA-1001
-INVALID_CURSOR
...
ORA-6533
-SUBSCRIPT_BEYOND_COUNT
51. 触发异常
RAISE exception_variable
DECLARE
A EXCEPTION
BEGIN
...
RAISE A;
...
EXCEPTION
WHEN A THEN
...
END;
52. 处理异常
EXCEPTION
WHEN e_TooManyStudents THEN
INSERT INTO log_file(info)
VALUES('Major 1100 has' || v_CurStudents || 'max aloowed is' || v_Max);
END;
53. 处理所有的异常
异常的传递
处理所有其他异常
EXCEPTION
WHEN e_TooManyStudents THEN
...
WHEN OTHERS THEN
v_ErrCode := SQLCODE;
v_ErrText := SUBSTR(SQLERRM, 1, 200);
INSERT INTO log_file(code, message, info)
VALUES(v_ErrCode, v_ErrCode, v_ErrText, 'ORACLE Error');
END;
54. 第七章
1.PL/SQL简介
2. PL/SQL程序结构
3. 变量与数据类型
4. PL/SQL控制语句
5. PL/SQL游标
6. 异常捕获
7. 子程序
1. 过程
2. 函数
8. 包
9. 触发器
55. 子程序
匿名块
-匿名块不存在于数据库中
-每次使用时都会进行编译
-不能在其他块中相互调用
带名块
-可存储于数据库中
-可以在任何需要的地方调用
-过程、函数、包、触发器
56. 过程
创建procedure
CREATE [OR REPLACE] PROCEDURE proc_name
[(arg_name[{IN | OUT | IN OUT}]TYPE,
...
arg_name[{IN | OUT | IN OUT}]TYPE)]
{IS | AS}
procedure_body
57. 过程的参数模式
IN
-在调用过程的时候,实际参数的值被传递给该过程;在过程内部,形参是只可读的。
OUT
-在调用过程时,任何的实参将被忽略;在过程内部,形参是只可写的。
IN OUT
-是IN与OUT 的组合,在调用过程的时候,实参的值可以被传递给该过程;在过程内部,形参也可以被读出也可以被写入;
过程结束时,控制会返回给控制环境,而形式参数的内容将赋给调用时的实际参数。
参数的缺省模式是IN
58. 过程的主体
PROCEDURE BODY
-过程的主体是一个拥有声明,执行和异常处理的完整的PL/SQL块
-声明部分在IS或AS关键字与BEGIN关键字之间
-执行部分在BEGIN和EXCEPTION之间
-异常处理在EXCEPTION与END之间
59. 过程的例子
CREATE OR REPLACE PROCEDURE ModeText(
p_InParm IN NUMBER,
p_OutParm OUT NUMBER,
p_InOut IN OUT NUMBER)
IS
v_LocalVar NUMBER;
BEGIN
v_LocalVar := p_InParm; //legal
p_InParm := 7; //illegal
p_OutParm := 7; //legal
v_LocalVar := p_OutParm; //illegal
v_LocalVar := p_InOutParm; //legal
p_InOutParm := 7; //legal
...
END ModeTest;
60. 调用过程的例子
DECLARE
v_var1 NUMBER := 1001;
v_var2 NUMBER := 1234;
BEGIN
ModeTest(10, v_var1, v_var2);
END;
DECLARE
v_var1 NUMBER;
BEGIN
ModeTest(12, v_var1, 10);
END;
61. 指定实参的模式
位置标示法
-调用时添入所有参数,实参与形参按顺序一一对应
名字标示法
-调用时给出形参名字,并给出实参
ModeTest(p_InParm => 12,
p_OutParm => v_var1,
p_InOut => 10);
两种方法可以混用
-混用时,第一个参数必须通过位置来指定
-名字标示法对于参数很多时,可提高程序的可读性
62. 使用缺省参数时
形参可以指明缺省值
parm_name[mode]type{:= | DEFAULT} init_value
位置标示法时,所有的缺省值都放在最后面
-使用名字标示法则无所谓
如果使用了缺省值,尽量将缺省值放在参数表的末尾
63. 函数
函数在所有的地方都与过程相似
-都有名字
-都有统一的形式:声明、执行与异常处理
-可以存储在数据库中,也可以声明在无名块的内部
差别
-过程调用本身是一个PL/SQL语句
-函数调用是表达式的一部分
注:▲ 另外,函数有返回值,而过程没有。
64. 函数的声明
CREATE [OR REPLACE] FUNCTION func_name
[(arg_name[{IN | OUT | IN OUT}]TYPE,
...
arg_name[{IN | OUT | IN OUT}]TYPE)]
RETURN TYPE
{IS | AS}
function_Body
65. RETURN语句
在函数的主体内部,return语句用来将控制通过一个数值返回给调用环境
- RETURN <表达式>;
在一个函数主体中,可以使用多个返回语句
没有返回语句的函数将是一个错误
66. 函数样式
函数可以通过OUT参数来返回多个数值
函数可以接收缺省参数
67. 删除过程与函数
DROP PROCEDURE procedure_name;
DROP FUNCTION function_name;
68. 子程序的位置
存储子程序
-通过CREATE OR REPLACE命令创建
-以编译后的形式存放在数据库中
本地子程序
-没有CREATE OR REPLACE关键字
-子程序的定义放在无名块的声明部分
-子程序被该无名块使用
69. 本地子程序
DECLARE
v_var VARCHAR2;
FUNCTION func(p_Fname IN VARCHAR2, p_Lname IN VARCHAR2)
RETURN VARCHAR2 IS
BEGIN
...
END func;
BEGIN
v_var := func('First Name', 'Last Name');
...
END;
70. 第八章
1.PL/SQL简介
2. PL/SQL程序结构
3. 变量与数据类型
4. PL/SQL控制语句
5. PL/SQL游标
6. 异常捕获
7. 子程序
1. 过程
2. 函数
8. 包
9. 触发器
71. 包
包是可以将相关对象存储在一起的PL/SQL结构
包只能存储在数据库中,不能是本地的。
包是一个带有名字的声明
相当于一个PL/SQL块的声明部分
在块的声明部分出现的任何东西都能出现在包中
包中可以包含过程、函数、游标与变量
可以从其他PL/SQL块中引用包,包提供了可用于PL/SQL的全局变量
72. 包规范
包头:包含了有关包的内容的信息
包头不含任何过程的代码
包规范的语法
CREATE [OR REPLACE] PACKAGE pack_name{IS | AS}
procedure_specification | function_specification |
variable_declaration | type_definition |
exception_declaration | cursor_declaration
END pack_name;
73. 包头的例子1
CREAE OR REPLACE PACKAGE pak_test AS
PROCEDURE AddStudent(p_StuID IN students.id%TYPE,
p_Dep IN classes.department%TYPE,
p_Course IN classes.course%TYPE);
PROCEDURE RemoveStudent(p_StuID IN students.id%TYPE);
e_StudentNotRegistered EXCEPTION;
TYPE t_StuIDTable IS TABLE OF students.id%TYPE INDEX
BY BINARY_INTEGER;
END pak_name;
74. 包头的例子2
在包pak_test中包含了两个过程,一个类型与一个异常
AddStudent
RemoveStudent
t_StuIDTable
e_StudentNotRegistered
包的部件可以按任意次序出现,但对象必须声明在被引用的前面
所有过程或函数的代码不能出现在包头中
75. 包主体
包主体是可选的,如果包头中没有任何函数与过程,则包主体可以不需要
包主体与包头存放在不同的数据字典中
如果包头的编译不成功,包主体就无法正确的编译出来
包主体中包含了在包头中声明的所有过程与函数的代码
过程与函数的规范在包头与包主体中必须一致
规范包括子程序的名字,参数的名字以及参数的模式:包括类型与顺序
76. 包主体的语法
CREATE OR REPLACE PACKAGE BODY pak_test AS
PROCEDURE AddStudent(p_StuID IN students.id%TYPE,
p_Dep IN classes.department%TYPE,
p_Course IN classes.course%TYPE) IS
BEGIN
...
END AddStudent;
PROCEDURE RemoveStudent(p_StuID IN students.id%TYPE) IS
BEGIN
...
END RemoveStudent;
END pak_test;
77. 包的作用域
在包头中声明的所有东西在包的外面都可以使用
使用时必须指明包的名字
直接调用包中的过程
pak_test.AddStudent(100010, 'CS', 101);
在包的主体中可以直接使用包头中声明的对象
不需要指明包的名字
78. 包中子程序的重载
同一个包中的过程与函数都可以重载
相同的过程或函数名字,但参数不同
重载不能仅仅依据是参数名字和模式不同
重载不能仅仅依据函数的返回类型
重载的参数必须是不同类型族
重载要求参数类型必须不同
而且要求是不同类型族的
无法区分CHAR与VARCHAR2
79. 包的初始化
包存放在数据库中
在第一次被调用的时候,包从数据库中调入内存并被初始化
包中定义的所有变量都被分配内存
每个会话都将拥有自己的包内变量的副本
可以指定包的初始化代码
CREATE OR REPLACE PACKAGE BODY pac_name{IS | AS}
...
BEGIN
--Initialization code
END pac_name;
80. 第九章
1.PL/SQL简介
2. PL/SQL程序结构
3. 变量与数据类型
4. PL/SQL控制语句
5. PL/SQL游标
6. 异常捕获
7. 子程序
1. 过程
2. 函数
8. 包
9. 触发器
81. 触发器
触发器与过程、函数类似
都是带有名字的执行块
都有声明、执行体和异常处理部分
触发器与过程、函数的差别
触发器必须存储在数据库中
对于过程和函数,必须显式地由另一个运行块调用
对于触发器,是由触发事件自动激发
触发事件是在数据库表上执行的DML数据操作
INSERT, UPDATE, DELETE
82. 触发器的作用
用于维护数据的完整性
有些复杂的数据完整性约束无法在创建表的时刻通过声明性约束解决
通过数据库表的记录的修改来执行审计功能
当表被修改的时候,自动给其他需要执行操作的程序发信号
83. 创建触发器
语法
CREATE [OR REPLACE] TRIGGER trigger_name
{BEFORE | AFTER} triggering_event ON table_reference
[FOR EACH ROW[WHEN trigger_condition]]
trigger_body;
必须的部分
触发器名:trigger_name
触发事件:triggering_event
触发器主体:trigger_body
可选部分
WHEN子句
84. 触发器的例子
CREATE OR REPLACE TRIGGER UpdateMajorStats
AFTER INSERT OR DELETE OR UPDATE ON students
DECLARE
CURSOR c_Statistics IS
SELECT major, COUNT(*) total_students, SUM(current_credits) total_credits
FROM students
GROUP BY major;
BEGIN
FOR v_StatsRecord in c_Statistics LOOP
UPDATE major_stats
SET total_credits = v_StatsRecord.total_credits,
total_students = v_StatsRecord.total_students
WHERE major = v_StatsRecord.major;
IF SQL%NOTFOUND THEN
INSERT INTO major_stats(major, total_credits, total_students)
VALUES(v_StatsRecord.major, v_StatsRecord.total_credits, v_StatsRecord.total_students);
END IF;
END LOOP;
END UpdateMajorStats;
85. 触发器组件
触发器名
-在同一个数据库中
过程、包与表的名字空间相同
触发器使用单独的名字空间
触发器可以与表同名
触发器类型
-触发事件决定了触发器的类型
语句:INSERT, UPDATE, DELETE
定时:BEFORE, AFTER
级别:
-行级触发器(FOR EACH ROW),对由触发语句影响的每一行点火一次
-语句级触发器,仅在语句执行前/后执行一次
86. 触发器类型
共有12种触发器类型
三个语句(INSERT/UPDATE/DELETE)
两种类型(之前/之后)
两种级别(row-level/statement-level)
一个表最多可以定义12个触发器
PL/SQL2.1以后版本,对于每种类型可以拥有多个触发器
87. 触发器的限制
触发器的主体是PL/SQL语句块
所有能出现在PL/SQL块中的语句在触发器主体中都是合法的限制
不应该使用事务控制语句
COMMIT, ROLLBACK, SAVEPOINT
由触发器调用的任何过程与函数都不能使用事务控制语句
不能声明任何LONG或LONG RAW变量
可以访问的表有限
88. 触发器的主体可以访问的表
变化表
被DML语句正在修改的表,亦即定义触发器的表
限制表
有些表在创建的时候就带有参考完整性限制的声明
主键与外键
触发器主体中的限制
不可以读取或修改任何变化表
不可以读取或修改限制表的主键,唯一值列,外键列
89. 相关信息
ORACLE产品与资料信息
http://www.oracle.com
ORACLE 8i的资料
http://gwynne.cs.ualberta.ca/~oracle/817doc/index.htm
90. 学籍管理信息库
设计一个data schema, 将tarena公司的学籍管理信息建立在数据库中
应该包括下列信息
学员信息
课程信息
班级信息
...
建立数据库表或相关视图
使用sqlplus?使用PL/SQL?
使用PL/SQL程序来完成
输入部分数据
完成简单查询功能
使用Pro*C完成下列功能
数据插入、修改与删除
数据查询
91. 系统使用记费系统
思考并设计记帐系统中使用的data schema
92. 谢谢
★好书推荐:
Oracle9i PL/SQL程序设计(Oracle9i PL/SQL Programming)
Oracle Express出品,官方、权威,秉承了麦格劳希尔一贯的严谨治学的作风,而且两位译者翻译也很到位
Oracle9i开发指南:PL/SQL程序设计(Oracle9i Developer: PL/SQL Programming)
该书提供了大量宝贵的实际练习机会,包括逐步操作的指导以及每一章中的复习题、课外作业以及实例研究