zoukankan      html  css  js  c++  java
  • PL/SQL(Procedure Language & Structured Query Language)

    目前的PL/SQL包括两部分,一部分是数据库引擎部分;另一部分是可嵌入到许多产品(如C语言,JAVA语言等)工具中的独立引擎。可以将这两部分称为:数据库PL/SQL和工具PL/SQL。

    PL/SQL中的基本单位是块(Block),所有PL/SQL程序都是由块组成的。PL/SQL中的块由3部分组成:声明部分,程序代码、异常处理代码。如下:

    DECLARE 

    /* 声明部分: 在此声明PL/SQL用到的变量,类型及游标,以及局部的存储过程和函数 */

    BEGIN

        /*  执行部分:  过程及SQL 语句  , 即程序的主要部分  */

    EXCEPTION

       /* 执行异常部分: 错误处理  */

    END;

    面试题:如何解决系统慢的问题?如果使用的是传统方法,就需要优化SQL语句,还有另一种方法就是将SQL语句用PL/SQL写成模块,存储在Oracle中,用的时候直接调用。

    好处:模块化的程序设计、更快、减少网络流量、提高代码的重用性和共享性、提高安全性(存储过程把表的具体字段封装好了)。

    缺点:移植性不好(如由Oracle转向DB2时,所有存储过程都要重写)

    一、过程

    创建过程语法:

    CREATE [OR REPLACE] PROCEDURE Procedure_name

    [ (argment [ { IN | IN OUT }] Type,

          argment [ { IN | OUT | IN OUT } ] Type ]

    { IS | AS }

    <类型.变量的说明>

    BEGIN

    <执行部分>

    EXCEPTION

    <可选的异常错误处理程序>

    END[Procedure_name];

      在PL/SQL 程序中还可以在块内建立本地函数和过程,这些函数和过程不存储在数据库中,但可以在创建它们的PL/SQL 程序中被重复调用。本地函数和过程在PL/SQL 块的声明部分定义,它们的语法格式与存储函数和过程相同,但不能使用CREATE OR REPLACE 关键字。

    二、函数

    创建函数语法:

    CREATE [OR REPLACE] FUNCTION function_name

    [(argment [ { IN| IN OUT }] type,

                argment [ { IN | OUT | IN OUT } ] type]

    RETURN return_type

    { IS | AS }

    <类型.变量的说明>

    BEGIN

    FUNCTION_body(最后含return语句)

    EXCEPTION

    其它语句

    END[function_name];

    三、包和包体

    创建包定义:

    CREATE [OR REPLACE] PACKAGE package_name

    [AUTHID {CURRENT_USER | DEFINER}]

    {IS | AS}

    [公有数据类型定义[公有数据类型定义]…]

    [公有游标声明[公有游标声明]…]

    [公有变量、常量声明[公有变量、常量声明]…]

    [公有子程序声明[公有子程序声明]…]

    END [package_name];

    创建包主体:

    CREATE [OR REPLACE] PACKAGE BODY package_name

    {IS | AS}

    [私有数据类型定义[私有数据类型定义]…]

    [私有变量、常量声明[私有变量、常量声明]…]

    [私有子程序声明和定义[私有子程序声明和定义]…]

    [公有游标定义[公有游标定义]…]

    [公有子程序定义[公有子程序定义]…]

    BEGIN(??有吗)

    PL/SQL 语句

    END [package_name];

    四、触发器

    共5种。

    创建触发器的一般语法是:

    CREATE [OR REPLACE] TRIGGER trigger_name

    {BEFORE | AFTER | INSTEAD OF}

    {INSERT | DELETE | UPDATE [OF column [, column …]]}

    ON {[schema.] table_name | [schema.] view_name}

    [REFERENCING {OLD [AS] old | NEW [AS] new| PARENT as parent}]

    [FOR EACH ROW ]

    [WHEN condition]

    trigger_body;

    REFERENCING 子句说明相关名称,在行触发器的PL/SQL块和WHEN 子句中可以使用相关名称参照当前的新、旧列值,默认的相关名称分别为OLD和NEW。触发器的PL/SQL块中应用相关名称时,必须在它们之前加冒号(:),但在WHEN子句中则不能加冒号。

    WHEN 子句说明触发约束条件。Condition 为一个逻辑表达时,其中必须包含相关名称,而不能包含查询语句,也不能调用PL/SQL 函数。WHEN 子句指定的触发约束条件只能用在BEFORE 和AFTER 行触发器中,不能用在INSTEAD OF 行触发器和其它类型的触发器中。

    触发器触发次序:

    step1:执行 BEFORE语句级触发器

    step2:对与受语句影响的每一行

      执行 BEFORE行级触发器

      执行 DML语句

      执行 AFTER行级触发器 

    step3:执行 AFTER语句级触发器

    触发器的限制

    l  CREATE TRIGGER语句文本的字符长度不能超过32KB;

    l  触发器体内的SELECT 语句只能为SELECT … INTO …结构,或者为定义游标所使用的SELECT 语句。

    l  触发器中不能使用数据库事务控制语句 COMMIT; ROLLBACK, SVAEPOINT 语句;

    l  由触发器所调用的过程或函数也不能使用数据库事务控制语句;

    l  触发器中不能使用LONG, LONG RAW 类型;

    l  触发器内可以参照LOB 类型列的列值,但不能通过 :NEW 修改LOB列中的数据;

    l  触发器所访问的表受到表的约束限制,即后面的“变化表”。

    问题:当触发器被触发时,要使用被插入、更新或删除的记录中的列值,有时要使用操作前、后列的值.实现:  

    :new  修饰符访问操作完成后列的值      

    :old  修饰符访问操作完成前列的值

    特性

    INSERT

    UPDATE

    DELETE

    OLD

    NULL

    有效

    有效

    NEW

    有效

    有效

    NULL

    1、语句触发器(是指当某触发事件发生时,该触发器只执行一次)

    CREATE [OR REPLACE] TRIGGER <触发器名>

    [BEFORE|AFTER] <触发事件> ON <表名>

    <PL/SQL程序体>

    2、行触发器(是指当某触发事件发生时,对受到该操作影响的每一行数据,触发器都单独执行一次)

    CREATE [OR REPLACE] TRIGGER <触发器名>

    [BEFORE|AFTER] <触发事件> ON <表名>

    FOR EACH ROW

    <PL/SQL程序体>

    当省略FOR EACH ROW 选项时,BEFORE 和AFTER 触发器为语句触发器,而INSTEAD OF 触发器则为行触发器。

    3、INSTEAD OF 触发器(只适用于视图,ORACLE激活触发器,而不执行触发事件)

    CREATE [OR REPLACE] TRIGGER <触发器名>

    INSTEAD OF <触发事件> ON <表名>

    <PL/SQL程序体>

    4、用户事件触发器

    5、系统事件触发器

  • 相关阅读:
    LuoguP1126 机器人搬重物(BFS)
    POJ1950----DFS
    C
    B
    A
    C
    B
    A
    A
    B
  • 原文地址:https://www.cnblogs.com/seven7seven/p/3730090.html
Copyright © 2011-2022 走看看