zoukankan      html  css  js  c++  java
  • pl/sql programming 03 语言基础

    PL/SQL 块结构

    最小的有意义的代码单元叫做 块(block). 一个块是一组代码, 这个块给出了执行边界, 也为变量声明和异常处理提供了作用范围, pl/sql 准许我们创建匿名块和命名块, 命名块包括 包, 过程, 函数, 触发器或者对象类型.

    一个Pl/SQL 块应该包含4个单元

    header   // 块头, 可选的 ( 只有命名块才会有这个单元, 比如 create function 等等

    IS

      declaration section  // 声明单元, 可选, 注意, 这里不需要在使用 declare 关键字了.

    BEGIN

      execution section    // 执行单元 , 这个单元是必须的

    EXCEPTION

      exception section    // 异常处理单元, 可选

    END;

    例如:

    PROCEDURE get_happy(ename_in IN VARCHAR2)   // 块头

    IS

      l_hiredate DATE;  // 声明单元

    BEGIN

      l_hiredate := SYSDATE - 2;    // 执行单元

      INSERT INTO employee (emp_name, hiredate)

      VALUES (ename_in, l_hiredate);

    EXCEPTION

      WHEN DUP_VAL_IN_INDEX THEN

        DBMS_OUTPUT.PUT_LINE (‘Cannot insert.’);

    END;

     嵌套块

    procedure calc_totals

    is

      year_total number;

    begin

      year_total := 0;

      /* 嵌套块的开始 */

      declare   -- 嵌套块内的声明部分就需要使用 declare 来声明了, 因为内部实际上市一个匿名块, 匿名块需要使用 declare

         month_total number;

      begin

        month_total := year_total / 12;

      end set_month_total;

      /* 嵌套块结束 */

    end;

    嵌套块: 还被叫做闭包块, 子块.

    1. 作用域, 要规范变量名, 要写全称, 例如:

    在 PL/SQL中, 变量, 异常, 模块 和一些其他的结构都是属于声明它们的块局部的. 即作用范围是, 当前块内部. 所以在外层快定义的变量, 在内层块可以访问.

       1:  /* Formatted on 2013/11/20 14:46 (Formatter Plus v4.8.6) */
       2:  PACKAGE scope_demo
       3:  IS
       4:     g_global   NUMBER;
       5:   
       6:     PROCEDURE set_global (number_in IN NUMBER);
       7:  END scope_demo;
       8:   
       9:  PACKAGE BODY scope_demo
      10:  IS
      11:    PROCEDURE set_global(number_in IN NUMBER)
      12:    IS
      13:        l_salary NUMBER := 10000;
      14:      l_count PLS_INTEGER;
      15:    BEGIN
      16:           <<local_block>>
      17:         DECLARE
      18:                   l_inner NUMBER;
      19:         BEGIN
      20:                 SELECT COUNT(*)
      21:              INTO set_global.l_count
      22:              FROM emplyees e
      23:              WHERE e.department_id = local_block.l_inner
      24:              AND e.salary > set_global.l_salary;
      25:         END local_block;
      26:         
      27:         scope_demo.g_global := set_global.number_in;
      28:    END set_global;
    这个包, 有点类似 OBJECT-C, 在包声明部分声明的内容为全局变量, 任何对 scope_demo 包有 execute 授权的模式的任何代码块都可以使用这个变量, scope_demo.g_global, 
    而 l_salary 这个变量只能在set_global过程内部使用, l_inner 这个变量只能被局部或者潜逃块内使用.

    规范sql语句中所有对变量和列的引用
    PACKAGE BODY scope_demo
    IS    
        PROCEDURE set_global (number_in IN NUMBER)
        IS
            l_salary NUMBER := 10000;
            l_count PLS_INTEGER;
        BEGIN
            <<local_block>>
            DECLARE
                l_inner PLS_INTEGER;
            BEGIN
                SELECT COUNT(*)
                    INTO set_global.l_count
                  FROM employees e
                 WHERE e.department_id = local_block.l_inner
                    AND e.salary > set_global.l_salary;
            END local_block;
        scope_demo.g_global := set_global.number_in;
      END set_global;
    
    END scope_demo;

    可以看到, 就是在引用一些变量 等内容时, 要写全称. 特别是外部块和内部块同名时. 

    通过上边例子的限定符, 避免Bug. 

    可见性

    • 一个在当前块声明的标示符
    • 一个在包含点前块的块中声明的标示符(即嵌套块内层能看到外层声明的变量)
    • 属于你所有的一个单独的数据库对象(表, 视图, 序列等) 或者pl/sql对象(过程, 函数, 类型)
    • 一个你能看到的数据库别名, 而且你对别名指向的数据库对象或者 pl/sql 对象有适当的权限.
    • 一个循环体中的索引变量(但这个变量的作用域只在循环体内)

    2. 单引号问题
    image

    q + 分隔符的办法
    image
    单行注释 --
    多行注释 /**/

    PRAGMA
    这个词, 暗示一个契约, 一个动作, 在PL/SQL中提供了以下几个内容:
    AUTONOMOUS_TRANSACTION , 当前块对数据库所做的修改的提交或回滚不影响主事务或者外层事务.
    EXCEPTION_INIT 把一个特殊的错误号和我们在程序中声明的异常标示符关联起来
    RESTRICT_REFERENCES 告诉编译器一个包程序的纯度级别.
    SERIALLY_REUSABLE 包级别的数据在引用间不能保留
    例如
    DECLARE
      no_such_sequence EXCEPTION;
      PRAGMA EXCEPTION_INIT (no_such_sequence, -2289);
    BEGIN
      WHEN no_such_sequence
      THEN
        q$error_manager.raise_error('Sequence not defined');
    END;

    3. 标签

    <<inner>>, <<outer>> 等等.

    作用:

    一个代码块, 有一个标签, 可以提高代码的可读性

    另外, 在变量名前指明标签, 可以规范代码变量.

    在代码块中, 可以方便操作, 例如 exit outer_loop, 虽然你在内层循环, 但是因为你写的是 exit outer_loop, 所以就可以退出外层循环.

  • 相关阅读:
    hash表学习笔记
    【学习笔记-集合】HashMap 源码浅析
    java 同步
    学习SpringBoot了
    记录一些好的 学习网站
    Idea 的页面布局设定,tomcat及普通web项目设定
    Spring 札记
    java面试题(基础+非基础)[不定期更新]
    maven 使用
    ant 生成报告时报错,Errors while applying transformations: Fatal error during transformation
  • 原文地址:https://www.cnblogs.com/moveofgod/p/3433591.html
Copyright © 2011-2022 走看看