PL/SQL学习八(PLSQL块与控制结构)

23. PL/SQL块
    注意PL/SQL块中只能直接嵌入SELECT、DML语句以及事务控制语句,而不能直接嵌入DDL语句和DCL语句(GRANT、REVOKE)。
   23.1 PL/SQL块嵌入SELECT语句
        注意接收变量INTO与SELECT的列的数量及数据类型要一致。

-- ex:pl/sql_12
--SQL*PLUS下开启输出显示
SQL> set serveroutput on
-- 定义匿名PL/SQL块
SQL> DECLARE
  2    V_ENAME EMP.ENAME%TYPE;
  3    V_SAL   EMP.SAL%TYPE;
  4
  5  BEGIN
  6    SELECT ENAME, SAL
  7    INTO V_ENAME, V_SAL
  8    FROM EMP WHERE EMPNO = &a;--手动输入empno的值
  9
 10    DBMS_OUTPUT.PUT_LINE('name:' || V_ENAME);
 11    DBMS_OUTPUT.PUT_LINE('sal:' || V_SAL);
 12 --异常处理
 13  EXCEPTION
 14    WHEN OTHERS THEN
 15      DBMS_OUTPUT.PUT_LINE('error');
 16  END;
 17  /
输入 a 的值:  7900
原值    8:   FROM EMP WHERE EMPNO = &a;
新值    8:   FROM EMP WHERE EMPNO = 7900;
name:JAMES
sal:950

PL/SQL 过程已成功完成。


 
   23.2 PL/SQL块中嵌入INSERT语句
        注意插入数据时,必须为表的主键列和NOT NULL列提供插入数据.

-- ex:pl/sql_13      
DECLARE
  --定义记录类型变量
  TYPE DEPT_RECORD_TYPE IS RECORD(
    V_DNAME  DEPT.DNAME%TYPE,
    V_DEPTNO DEPT.DEPTNO%TYPE);

  DEPT_RECORD DEPT_RECORD_TYPE;

BEGIN
 --给记录的各变量赋值
  DEPT_RECORD.V_DEPTNO := &NO;
  DEPT_RECORD.V_DNAME  := '&name';
--插入dept表
  INSERT INTO DEPT(deptno,dname) VALUES (DEPT_RECORD.V_DEPTNO,DEPT_RECORD.V_DNAME);

EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('Insert error!');
END;
--SQL*PLUS下测试
SQL> /
输入 no 的值:  60
原值    9:   DEPT_RECORD.V_DEPTNO := &NO;
新值    9:   DEPT_RECORD.V_DEPTNO := 60;
输入 name 的值:  Test
原值   10:   DEPT_RECORD.V_DNAME  := '&name';
新值   10:   DEPT_RECORD.V_DNAME  := 'Test';

PL/SQL 过程已成功完成。


         
   23.3 PL/SQL中使用UPDATE语句
        注意更新列值时要满足该列的各种约束条件.

-- ex:pl/sql_14
DECLARE
  --定义变量
  V_ENAME EMP.ENAME%TYPE;

BEGIN
  --给变量赋值
  V_ENAME := '&name';
  --使用子查询更新额emp表
  UPDATE EMP
     SET (SAL, COMM) = (SELECT SAL, COMM FROM EMP WHERE ENAME = V_ENAME)
   WHERE JOB = (SELECT JOB FROM EMP WHERE ENAME = V_ENAME);

EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('Update error!');
END;
--SQL*PLUS测试
SQL> /
输入 name 的值:  ALLEN
原值    7:   V_ENAME := '&name';
新值    7:   V_ENAME := 'ALLEN';

PL/SQL 过程已成功完成。  


    
             
   23.4 PL/SQL中使用DELETE语句
        注意删除的时候,有主外键约束的话,那么删除主表(没有外键约束的那个表)的时候,会出错。

-- ex:pl/sql_15
DECLARE
  --定义变量
  V_ENAME EMP.ENAME%TYPE;

BEGIN
  --给变量赋值
  V_ENAME := '&name';
  --使用子查询删除emp表相关数据
  DELETE FROM EMP
   WHERE DEPTNO = (SELECT DEPTNO FROM EMP WHERE ENAME = V_ENAME);

EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('Delete error!');
END;
--SQL*PLUS下测试
SQL> /
输入 name 的值:  ALLEN
原值    7:   V_ENAME := '&name';
新值    7:   V_ENAME := 'ALLEN';

PL/SQL 过程已成功完成。


         
   23.5 PL/SQL中使用游标(CURSOR)
       游标的几种属性SQL%FOUND,SQL%NOTFOUND,SQL%ROWCOUNT,SQL%ISOPEN。

-- ex:pl/sql_16        
DECLARE
  --定义行变量
  V_EMP EMP%ROWTYPE;

BEGIN
  SELECT * INTO V_EMP FROM EMP WHERE ROWNUM = 1;
  --隐式游标属性SQL%ISOPEN,隐式游标自动打开关闭,SQL%ISOPEN永为FALSE.
  IF SQL%ISOPEN THEN
    DBMS_OUTPUT.PUT_LINE('Cursor is open');
  ELSE 
    DBMS_OUTPUT.PUT_LINE('Cursor is close');
  END IF ;
  --隐式游标属性SQL%FOUND
  IF SQL%FOUND THEN
    DBMS_OUTPUT.PUT_LINE('name1:' || V_EMP.ENAME);
  ELSE
    DBMS_OUTPUT.PUT_LINE('no data Found11');
  END IF;
  --隐式游标属性SQL%NOTFOUND
  IF SQL%NOTFOUND THEN
    DBMS_OUTPUT.PUT_LINE('no data Found22');
  
  ELSE
    DBMS_OUTPUT.PUT_LINE('name2:' || V_EMP.ENAME);
  END IF;
  --隐式游标属性SQL%COUNT 
  UPDATE EMP SET SAL = SAL * 1.3 WHERE DEPTNO = V_EMP.DEPTNO;
  DBMS_OUTPUT.PUT_LINE('修改了 ' || SQL%ROWCOUNT || ' 行数据');
EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('error!');
END;
--SQL*PLUS下测试
Cursor is close        
name1:SMITH
name2:SMITH
修改了 3 行数据

PL/SQL 过程已成功完成。      


                
    23.6 PL/SQL中使用事务控制语句

-- ex:pl/sql_17
BEGIN
  UPDATE EMP SET SAL = sal+SAL * 1.1;
  SAVEPOINT UP1;

  INSERT INTO DEPT (DEPTNO, DNAME) VALUES (50, 'Hello');
  SAVEPOINT IN2;

  DELETE FROM EMP WHERE DEPTNO = 10;
  SAVEPOINT DE3;

  DBMS_OUTPUT.PUT_LINE('DML全部操作完成.');

  ROLLBACK TO IN2;
  DBMS_OUTPUT.PUT_LINE('回滚到插入操作后状态.');
  COMMIT;
  DBMS_OUTPUT.PUT_LINE('提交完成');

EXCEPTION
  WHEN OTHERS THEN
    ROLLBACK;
    DBMS_OUTPUT.PUT_LINE('DML操作出错!');
  
END;
--SQL*PLUS下测试
DML全部操作完成.
回滚到插入操作后状态.
提交完成

PL/SQL 过程已成功完成。      


        
24. 控制结构
    分为条件分支结构、循环结构和顺序结构.
    24.1 条件分支结构
         三种语句:IF-THEN,IF-THEN-ELSE,IF-THEN-ELSIF(注意没有E,不是ELSEIF)

-- ex:pl/sql_18
SQL> DECLARE
  2  V_num NUMBER:=77;
  3  BEGIN
  4  IF v_num>=90 THEN
  5  dbms_output.put_line('A');
  6  ELSIF v_num>=80 AND v_num<90 THEN
  7  dbms_output.put_line('B');
  8  ELSIF v_num>=60 AND v_num<80 THEN
  9  dbms_output.put_line('C');
 10  ELSE
 11  dbms_output.put_line('D');
 12  END IF;
 13
 14  EXCEPTION
 15   WHEN OTHERS THEN
 16   dbms_output.put_line('Error!');
 17  END;
 18  /
C

PL/SQL 过程已成功完成。

 

多重分支结构CASE语句.

-- ex:pl/sql_19
declare
  v_deptno dept.deptno%type;

begin
  v_deptno := &no;
  case v_deptno
    when 30 then
      dbms_output.put_line('部门号为30!');
    when 20 then
      dbms_output.put_line('部门号为20!');
    when 10 then
      dbms_output.put_line('部门号为10!');
    else
      dbms_output.put_line('不存在此部门号');
    
  end case;

exception
  when others then
    dbms_output.put_line('CASE语句出错');
end;

输入no: 10
部门号为20!


        循环结构(LOOP、WHILE、FOR).

-- ex:pl/sql_20
DECLARE
  V_NUM INTEGER := 1;
  V_SUM INTEGER := 0;
BEGIN
  LOOP
    V_SUM := V_NUM + V_SUM;
    V_NUM := V_NUM + 1;
    EXIT WHEN V_NUM = 101;
  END LOOP;

  DBMS_OUTPUT.PUT_LINE('1到100的和为:' || V_SUM);

EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('LOOP语句出错');
END;

输出:
1到100的和为:5050


 

-- ex:pl/sql_21
DECLARE
  V_NUM INTEGER := 1;
  V_SUM INTEGER := 0;
BEGIN
  WHILE V_NUM != 101 LOOP 
    V_SUM := V_NUM + V_SUM;
    V_NUM := V_NUM + 1;
  END LOOP;

  DBMS_OUTPUT.PUT_LINE('1到100的和为:' || V_SUM);

EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('WHILE语句出错');
END;

输出:
1到100的和为:5050


 

-- ex:pl/sql_22
DECLARE
  V_SUM INTEGER := 0;
BEGIN
  FOR V_NUM IN 1..100 LOOP 
    V_SUM := V_NUM + V_SUM;
  END LOOP;

  DBMS_OUTPUT.PUT_LINE('1到100的和为:' || V_SUM);

EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('FOR语句出错');
END;

输出:
1到100的和为:5050


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值