zoukankan      html  css  js  c++  java
  • 创建触发器

    创建触发器的语法格式如下图:

    CREATE TRIGGER语句用于将触发器添加到数据库中。 所谓触发器是指在发生指定的数据库事件时自动执行的数据库操作。通常情况下,触发器必须指定一个关联表,当这个关联表发生了触发器指定的操作时,触发器就将自动进行定义的操作。

    例如:

    CREATE TRIGGER tri_t1 before insert on t1 
    Begin
    ……
    End.

    通常情况下,触发器有三个要素:

    • 时机,即什么时候启动触发器。
    • 条件,即启动触发器的条件。
    • 关联表,这个是触发器关联的数据表,当数据表删除时,也会自动删除创建的触发器;

          在SQLITE中,时机部分是可忽略的(默认是before),而条件是不允许省略的,每个触发器必须指定将针对以下操作之一触发:DELETE,INSERT,UPDATE。 触发器为删除,插入或更新的每一行触发一次。    

          如果BEFORE UPDATE或BEFORE DELETE触发器修改或删除了将要更新或删除的行,则后续更新或删除操作的结果很难确定。 此外,如果BEFORE触发器修改或删除了一行,则不确定是否会触发在其他行上的AFTER触发器。因此,如果使用BEFORE,则尽量不要对改行数据进行删除或更改。

          此外,在INSERT操作中使用BEFORE操作时,如果表中没有显示的ID栏,则不会更改NEW.rowid的值。当然,通常情况下,此时的NEW.rowid值通常情况下也不重要。事实上,如果定义了非空的ID值,而在插入数据前并不知道这个值时,使用BEFORE INSERT的触发器其实挺方便有效的。

        例如,每次插入数据时,设置NEW.ID为max(ID)+1,即可以避免缺少非空值的缺乏而报警,又能避免ID值重复。

        通过在CREATE TRIGGER语句中指定INSTEAD OF,可以在视图以及普通表上创建触发器。 如果在视图上定义了一个或多个ON INSERT,ON DELETE或ON UPDATE触发器,那么分别在视图上执行INSERT,DELETE或UPDATE语句就不会出错。 而是在视图上执行INSERT,DELETE或UPDATE会引发关联的触发器。 视图基础的实际表不会被修改(可能由触发程序明确修改除外)。

        如果使用“ UPDATE OF column-name”语法,则仅当column-name(指定的列)出现在UPDATE语句的SET子句中某个术语的左侧时,触发器才会触发。

       有意思的是,由于历史上的疏忽,“ UPDATE OF”子句中命名的列实际上不必存在于要更新的表中, 无法识别的列名将被自动忽略。当然如果之后你在表中增加了该名称的列,则触发器又会自动生效。

        目前,SQLite仅支持FOR EACH ROW触发器,不支持FOR EACH STATEMENT触发器。 因此,显式指定FOR EACH ROW是可选的。 FOR EACH ROW表示可以对引起触发器触发的语句插入,更新或删除的每个数据库行执行触发器中指定的SQL语句(取决于WHEN子句)。

        WHEN子句和触发操作都可以使用“ NEW.column-name”和“ OLD.column-name”形式的引用来访问要插入,删除或更新的行的元素,其中column-name是 与触发器关联的表中的列。 OLD(表示原数据)和NEW(表示新数据)引用只能在与其相关的事件的触发器中使用,如下所示:

    • insert时,只有NEW
    • delete时,只有OLD
    • 而UPDATA时,既有NEW,也有OLD

    最后,让我们来看几个例子:

    例子1.假设客户记录存储在“customers”表中,而订单记录存储在“orders”表中,则以下UPDATE触发器可确保在客户更改其地址时重定向所有关联的订单:

    CREATE TRIGGER update_customer_address UPDATE OF address ON customers 
      BEGIN
        UPDATE orders SET address = new.address WHERE customer_name = old.name;
      END;

    当创建此触发器后,如果执行下面的语句:

    UPDATE customers SET address = '1 Main St.' WHERE name = 'Jack Jones';

    则自动导致下面的操作:

    UPDATE orders SET address = '1 Main St.' WHERE customer_name = 'Jack Jones';

    例子2,使用INSTEAD OF的触发器。假定我们使用下面的语句建立了表、视图和触发器:

    CREATE TABLE customer(
      cust_id INTEGER PRIMARY KEY,
      cust_name TEXT,
      cust_addr TEXT
    );
    
    CREATE VIEW customer_address AS
       SELECT cust_id, cust_addr FROM customer;
    CREATE TRIGGER cust_addr_chng
    
    INSTEAD OF UPDATE OF cust_addr ON customer_address
    BEGIN
      UPDATE customer SET cust_addr=NEW.cust_addr
       WHERE cust_id=NEW.cust_id;
    END;

    则下面的语句:

    UPDATE customer_address SET cust_addr=$new_address WHERE cust_id=$cust_id;

    导致为customer.cust_id等于$ cust_id参数的特定客户条目更新customer.cust_addr字段。

    最后说一句,删除触发器的语法是:

    drop trigger tablename

        

  • 相关阅读:
    无锁队列以及ABA问题
    bigworld源码分析(3)——dbMgr分析
    bigworld源码分析(4)——BaseAppMgr分析
    bigworld源码分析(5)——BaseApp分析
    bigworld源码分析(2)—— loginApp分析
    bigworld源码分析(1)—— 研究bigworld的意义和目标
    C++嵌入Python,以及两者混用
    B-Tree算法分析与实现
    通过sqlserver日志恢复误删除的数据
    win7启动时怎么自动进入桌面
  • 原文地址:https://www.cnblogs.com/luohq001/p/13215428.html
Copyright © 2011-2022 走看看