当前位置: 首页 > news >正文

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 + 分隔符的办法
单行注释 --
多行注释 /**/

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, 所以就可以退出外层循环.

 

转载于:https://www.cnblogs.com/moveofgod/p/3433591.html

相关文章:

  • 【mysql基础】mysql学习笔记-2-存储引擎
  • 如何形成高端战力
  • java acm输入输出
  • Exchange210中的Rpc Client Access server属性
  • mysql5.5 主从复制 (触发器,函数,存储引擎,事件处理)说明
  • jstack dump日志文件详解
  • list模块
  • vim 光标按行移动
  • Exchange2010跨林迁移邮箱(3)
  • 叨叨PS那些活
  • 合法的用户名
  • Mysql 索引 (转)
  • ListView项目长按的菜单功能总结
  • 通过扩展让ASP.NET Web API支持W3C的CORS规范
  • 【循序渐进学Python】12.Python 正则表达式简介
  • 《微软的软件测试之道》成书始末、出版宣告、补充致谢名单及相关信息
  • ABAP的include关键字,Java的import, C的include和C4C ABSL 的import比较
  • canvas 五子棋游戏
  • const let
  • co模块的前端实现
  • jdbc就是这么简单
  • python学习笔记-类对象的信息
  • Windows Containers 大冒险: 容器网络
  • 不用申请服务号就可以开发微信支付/支付宝/QQ钱包支付!附:直接可用的代码+demo...
  • 技术攻略】php设计模式(一):简介及创建型模式
  • 前端之Sass/Scss实战笔记
  • 新手搭建网站的主要流程
  • 智能合约Solidity教程-事件和日志(一)
  • [Shell 脚本] 备份网站文件至OSS服务(纯shell脚本无sdk) ...
  • ​VRRP 虚拟路由冗余协议(华为)
  • ​中南建设2022年半年报“韧”字当头,经营性现金流持续为正​
  • ###STL(标准模板库)
  • #includecmath
  • ()、[]、{}、(())、[[]]命令替换
  • (04)Hive的相关概念——order by 、sort by、distribute by 、cluster by
  • (LeetCode C++)盛最多水的容器
  • (MATLAB)第五章-矩阵运算
  • (PyTorch)TCN和RNN/LSTM/GRU结合实现时间序列预测
  • (二)c52学习之旅-简单了解单片机
  • (附源码)springboot码头作业管理系统 毕业设计 341654
  • (黑马C++)L06 重载与继承
  • (原創) 如何讓IE7按第二次Ctrl + Tab時,回到原來的索引標籤? (Web) (IE) (OS) (Windows)...
  • .net core 源码_ASP.NET Core之Identity源码学习
  • .net core使用RPC方式进行高效的HTTP服务访问
  • .NET Micro Framework初体验
  • .NET业务框架的构建
  • /usr/lib/mysql/plugin权限_给数据库增加密码策略遇到的权限问题
  • [ NOI 2001 ] 食物链
  • [2018/11/18] Java数据结构(2) 简单排序 冒泡排序 选择排序 插入排序
  • [Angularjs]asp.net mvc+angularjs+web api单页应用之CRUD操作
  • [AutoSar]BSW_Com02 PDU详解
  • [BZOJ] 2427: [HAOI2010]软件安装
  • [BZOJ4566][HAOI2016]找相同字符(SAM)
  • [C++] 多线程编程-thread::yield()-sleep_for()
  • [CSS] - 修正IE6不支持position:fixed的bug