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