课程 十一 与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
  1  declare
  2  v_deptno number(2);
  3  v_loc varchar2(15);
  4  begin
  5     select deptno,loc
  6       into v_deptno,v_loc
  7      from dept
  8      where dname='SALES';
  9  DBMS_OUTPUT.PUT_LINE (V_deptno ||' and '||v_loc);
 10* end;
30 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;
/
    大家多多实践即可掌握。
    PLSQL首先检查一个标识符是否是一个数据库的列名,如果不是,再假定它是一个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
  1  declare
  2    v_deptno number:=10;
  3    begin
  4      delete from emp where
  5       deptno=v_deptno;
  6       :row_de:=sql%rowcount;
  7* 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 dept.loc%type;
V_FLAG BOOLEAN ;
V_REC BOOLEAN :=FALSE; --此值改为TRUE、NULL、FALSE进行不同的比较
V_AVA BOOLEAN:=NULL;
    begin
V_FLAG:=V_REC AND V_AVA;
IF V_FLAG=TRUE THEN
   DBMS_OUTPUT.PUT_LINE ('TRUE');
ELSIF V_FLAG=FALSE THEN
   DBMS_OUTPUT.PUT_LINE ('FALSE');
ELSE
  DBMS_OUTPUT.PUT_LINE ('NULL');
END IF;
 end;
/
   值得注意的是:NULL AND FALSE ---> FALSE
   这是在实践中总结出来的。
   三、基本循环基础:
   1、LOOP
statement1;
statement2;
. . .
EXIT [WHEN condition];
END LOOP;
   v_ord_id s_item.ord_id%TYPE := 101;
v_counter NUMBER (2) := 1;
BEGIN
. . .
LOOP
INSERT INTO s_item (ord_id, item_id)
VALUES (v_ord_id, v_counter);
v_counter := v_counter + 1;
EXIT WHEN v_counter > 10;
END LOOP;
    2、FOR循环:
  FOR index IN [REVERSE] lower_bound..upper_bound LOOP
statement1;
statement2;
. . .
END LOOP;
         
    实例:DECLARE
  V_LOWER NUMBER:=1;
   V_UPPER NUMBER:=23;
BEGIN
DBMS_OUTPUT.PUT_LINE(');
   FOR I IN V_LOWER..V_UPPER LOOP
DBMS_OUTPUT.PUT_LINE(I);
END LOOP;
END;
/
    3、WHILE 循环:
   WHILE condition LOOP
statement1;
statement2;
. . .
END LOOP;
   4、循环是可以多层嵌套的。可以用<<LABEL>>做循环的标签。
...
BEGIN
<<Outer–loop>>LOOP
v_counter :=v_counter+1;
EXIT WHEN v_counter>10;
<<Inner–loop>>LOOP
...
EXIT Outer_loop WHEN total_done = ’YES’;
–– Leave both loops
EXIT WHEN inner_done = ’YES’;
–– Leave inner loop only
...
END LOOP Inner_Loop;
...
END LOOP Outer_loop;
END;
          
    总结:本章内容较为繁杂,虽然不是很难,而且多数与其他高级语言有某种共性,但大家要多多练习,用实践来检验对某些含糊的猜测。