您的位置:1010cc时时彩经典版 > 1010cc安卓版 > 1010cc时时彩经典版:Oracle数据库之PL,创建触发器

1010cc时时彩经典版:Oracle数据库之PL,创建触发器

发布时间:2019-08-11 07:21编辑:1010cc安卓版浏览(147)

    背景

      上一篇中,笔者介绍了SQL Server 允许访谈数据库的元数据,为啥有元数据,怎样选择元数据。这一篇中笔者会介绍如何特别找到种种有价值的信息。以触发器为例,因为它们往往一同相当多难题。

     

    触发器能够精晓为由特定事件触发的蕴藏进度, 和积存进度、函数一样,触发器也支撑CLHaval,近来SQL Server共帮助以下三种触发器:

    Oracle数据库之PL/SQL触发器

    1. 介绍

    触发器(trigger)是数据库提要求程序猿和多少深入分析员来保险数据完整性的一种格局,它是与表事件相关的特别规的仓库储存进程,它的实践不是由程序调用,亦不是手工业运行,而是由事件来触发,举例当对贰个表实行操作(insert,delete,update)时就能激活它实施。触发器平常用来狠抓数据的完整性约束和专业法规等。

    Oracle触发器有三种档案的次序,分别是:DML触发器、替代触发器和系统触发器。

    DML触发器

    顾名思义,DML触发器是由DML语句触发的。举例数据库的INSERT、UPDATE、DELETE操作都能够触发该项指标触发器。它们得以在这几个讲话在此以前或以往触发,或然在行级上接触(正是说对于每一个受影响的行都触发一遍)。

    代替触发器

    代表触发器只好使用在视图上,与DML不一致的是,DML触发器是运作在DML之外的,而顶替触发器是顶替激发它的DML语句运营。代替触发器是行触发器。

    系统触发器

    这种触发器是发出在如数据库运转或关闭等系统事件时,不是在推行DML语句时产生,当然也得以在DDL时接触。

    触发器作用庞大,轻巧可信赖地促成无数参差不齐的功力,不过我们也应有慎用。为何又要慎用呢?触发器自个儿并未有偏差,但如果大家滥用,会促成数据库及应用程序的保护困难。在数据库操作中,我们得以由此关系、触发器、存款和储蓄进程、应用程序等来落实数据操作,同一时候约束、缺省值也是保障数据完整性的重视保证。如若我们对触发器过分的凭借,势必影响数据库的布局,同时增添了珍爱的复杂程度。

    2. 触发器组成

    触发器紧要由以下多少个因素构成:

    1. 接触事件:引起触发器被触发的事件。
    2. 接触时间:触发器是在接触事件产生此前(BEFORE)依然之后(AFTEMurano)触发,也正是接触事件和该触发器的操作顺序。
    3. 接触操作:触发器被触发之后的目标和意向,是触发器本人要做的事体。
    4. 接触对象:富含表、视图、情势、数据库。独有在那一个目的上发出了适合触发条件的接触事件,才会进行触发操作。
    5. 接触条件:由WHEN子句钦定三个逻辑表达式。只有当该表明式的值为TRUE时,境遇触发事件才会自动推行触发器,使其施行触发操作。
    6. 触发频率:表达触发器钦定义的动作被实施的效用。即语句级(STATEMENT)触发器和行级(ROW)触发器: 
      语句级(STATEMENT)触发器:是指当某触发事件爆发时,该触发器只实行一遍; 
      行级(ROW)触发器:是指当某触发事件时有爆发时,对饱受该操作影响的每一行数据,触发器都独立实践二次。

    3. 创立触发器

    语法:

    CREATE [ OR REPLACE ] TRIGGER plsql_trigger_source
    

    plsql_trigger_source ::=

    [schema.] trigger_name
      { simple_dml_trigger
      | instead_of_dml_trigger
      | compound_dml_trigger
      | system_trigger
      }
    

    simple_dml_trigger ::=

    { BEFORE | AFTER } dml_event_clause [ referencing_clause ] [ FOR EACH ROW ]
      [ trigger_edition_clause ] [ trigger_ordering_clause ]
        [ ENABLE | DISABLE ] [ WHEN ( condition ) ] trigger_body
    

    instead_of_dml_trigger ::=

    INSTEAD OF { DELETE | INSERT | UPDATE } [ OR { DELETE | INSERT | UPDATE } ]...
    ON [ NESTED TABLE nested_table_column OF ] [ schema. ] noneditioning_view
    [ referencing_clause ] [ FOR EACH ROW ]
    [ trigger_edition_clause ] [ trigger_ordering_clause ]
    [ ENABLE | DISABLE ] trigger_body
    

    system_trigger ::=

    { BEFORE | AFTER | INSTEAD OF }
    { ddl_event [OR ddl_event]...
    | database_event [OR database_event]...
    }
    ON { [schema.] SCHEMA
       | DATABASE
       }
    [ trigger_ordering clause ]
    

    dml_event_clause ::=

    { DELETE | INSERT | UPDATE [ OF column [, column ]... ] }
    [ OR { DELETE | INSERT | UPDATE [ OF column [, column]... ] }...
    ON [ schema.] { table | view }
    

    referencing_clause ::=

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

    trigger_body ::=

    { plsql_block | CALL routine_clause }
    

    全部的语法结构见:

    说明:

    BEFORE和AFTEENVISION提出触发器的接触时间分别为前触发和后触发方式,前触发是在实践触发事件以前接触当前所开创的触发器,后触发是在实行触发事件之后触发当前所创设的触发器。

    REFERENCING子句表达有关称号,在行触发器的PL/SQL块和WHEN子句中能够使用相关称号参照当前的新、旧列值,私下认可的有关称号为OLD和NEW。触发器的PL/SQL块中利用相关称号时,必须在它们在此以前加冒号(:),但在WHEN子句中则不能够加冒号。

    NEW只在UPDATE、INSERT的DML触发器内可用,它涵盖了修改发生后被潜濡默化行的值。

    OLD只在UPDATE、DELETE的DML触发器内可用,它含有了退换产生前被影响行的值。

    FO昂Cora EACH ROW选项表达触发器为行触发器。行触发器和言辞触发器的界别表今后:行触发器须求当二个DML语句操走影响数据库中的多行数据时,对于里边的每一种数据行,只要它们符合触发约束规范,均激活二遍触发器;而讲话触发器将全体讲话操作作为触发事件,当它适合约束规范时,激活一遍触发器。当省略FOR EACH ROW 选项时,BEFORE和AFTELX570触发器为语句触发器,而INSTEAD OF触发器则不得不为行触发器。

    WHEN子句表明触发约束原则。Condition为三个逻辑表明时,其中必须含有相关称号,而无法富含查询语句,也不可能调用PL/SQL函数。WHEN子句内定的触发约束规范只好用在BEFORE和AFTETiguan行触发器中,不能用在INSTEAD OF行触发器和任何项目标触发器中。

    INSTEAD OF选项(成立代替触发器)使ORACLE激活触发器,而不试行触发事件。只好对视图和目的视图创立INSTEAD OF触发器,而不可能对表、格局和数据库建构INSTEAD OF触发器。

    ddl_event:三个或多少个DDL事件,事件间用O陆风X8分开。

    database_event:多个或四个数据库事件,事件间用O劲客分开。

    亲自去做1,在插入数据时,自动使用连串编号:

    CREATE OR REPLACE TRIGGER EMP_INSERT_ID
    BEFORE INSERT ON employee FOR EACH ROW
    BEGIN
       SELECT SEQ_ID.NEXTVAL INTO :NEW.ID FROM DUAL;
    END;
    

    示例2,在多表联接的视图中插入数据:

    -- 创建视图
    CREATE OR REPLACE VIEW vw_emp AS
    SELECT e.name ename, e.address, d.name dname
    FROM employee e, dept d
    WHERE e.did = d.id;
    
    -- 创建触发器
    CREATE TRIGGER emp_insert_trigger
       INSTEAD OF INSERT ON vw_emp
    DECLARE
       v_did dept.id%TYPE;
    BEGIN
       SELECT id INTO v_did FROM dept WHERE name = :NEW.dname;
       INSERT INTO emp (name, address, did) VALUES (:NEW.ename, :NEW.address, v_did);
    END emp_insert_trigger;
    

    示例3,创制实例运转触发器:

    -- 创建记录操作事件的表
    CREATE TABLE event_table(
       event VARCHAR2(50),
       time DATE
    );
    
    -- 创建触发器
    CREATE OR REPLACE TRIGGER tr_startup
       AFTER STARTUP
       ON DATABASE
    BEGIN
       INSERT INTO event_table(event, time)
        VALUES(ora_sysevent, SYSDATE);
    END;
    

    4. DML触发器

    DML触发器对大家开拓职员来说是最常用的。DML触发器是由数据库的INSERT、UPDATE、DELETE操作触发,该类触发器可以在上述讲话此前或以后实践,也得以每种受影响的行施行叁回。

    标准化谓词:当在触发器中带有多个触发事件(INSERT、UPDATE、DELETE)的结合时,为了分别指向不一样的风云张开区别的拍卖,必要选用ORACLE提供的尺度谓词:

    1. INSERTING:当触发事件是INSERT时,取值为TRUE,不然为FALSE。
    2. UPDATING [(column_1,column_2,…,column_x)]:当触发事件是UPDATE时,倘诺改变了column_x列,则取值为TRUE,不然为FALSE。
    3. DELETING:当触发事件是DELETE时,则取值为TRUE,不然为FALSE。

    示例:

    CREATE OR REPLACE TRIGGER emp_sal_trigger
       BEFORE UPDATE OF salary OR DELETE
       ON employee FOR EACH ROW
       WHEN (old.did = 1)
    BEGIN
      CASE
         WHEN UPDATING ('salary') THEN
            IF :NEW.salary < :old.salary THEN
               RAISE_APPLICATION_ERROR(-20001, '部门1的员工工资不能降');
            END IF;
         WHEN DELETING THEN
              RAISE_APPLICATION_ERROR(-20002, '不能删除部门1的员工记录');
      END CASE;
    END emp_sal_trigger;
    

    5. 代表触发器

    INSTEAD OF用于对视图的DML触发,由于视图有十分的大希望是由四个表联结(JOIN)而成,由此不用全数的视图都以可更新的,但足以坚守所需的议程实行更新。

    始建INSTEAD OF触发器要求留心以下几点:

    1. 不得不被创制在视图上,並且该视图未有一点名WITH CHECK OPTION选项。
    2. 不可能钦命BEFORE或AFTE科雷傲选项。
    3. FOHaval EACH ROW子句是可选的。
    4. 一向不须要在针对三个表的视图上创办INSTEAD OF触发器,只要创建DML触发器就足以了。

    示例:

    CREATE OR REPLACE TRIGGER emp_delete_trigger
       INSTEAD OF DELETE ON vw_emp FOR EACH ROW
    DECLARE
       v_did dept.id%TYPE;
    BEGIN
       SELEC id INTO v_did FROM dept WHERE name=:OLD.dname;
       DELETE FROM employee WHERE did= v_did;
    END emp_delete_trigger;
    

    6. 类别触发器

    系统触发器能够在DDL或数据库系统上被触发,数据库系统事件富含数据库服务器的启航或关闭,用户的记名与脱离、数据库服务错误等。

    系统事件触发器不仅可以够创设在三个形式上,又能够建设构造在全部数据库上。当创设在方式(SCHEMA)之上时,独有情势所钦命用户的DDL操作和它们所导致的失实才激活触发器,默许时为当下用户情势。当建构在数据库(DATABASE)之上时,该数据库全部用户的DDL操作和她俩所变成的谬误,以及数据库的运行和停业均可激活触发器。

    系统触发器的连串和事件出现的火候:

    事件 触发时机 说明
    STARTUP AFTER 启动数据库实例之后触发
    SHUTDOWN BEFORE 关闭数据库实例之前触发
    SERVERERROR AFTER 数据库服务器发生错误之后触发
    LOGON AFTER 成功登录到数据库后触发
    LOGOFF BEFORE 断开数据库连接之前触发
    DDL BEFORE,AFTER 在执行大多数DDL语句之前、之后触发
    CREATE / ALTER / DROP BEFORE,AFTER 在执行CREATE或ALTER或DROP语句创建数据库对象之前、之后触发
    RENAME BEFORE,AFTER 执行RENAME语句更改数据库对象名称之前、之后触发
    GRANT / REVOKE BEFORE,AFTER 执行GRANT语句授予权限或REVOKE撤销权限之前、之后触发
    AUDIT / NOAUDIT BEFORE,AFTER 执行AUDIT或NOAUDIT进行审计或停止审计之前、之后触发

    示例:

    -- 创建记录用户登录注销日志的表
    CREATE TABLE log_on_off_log
    (user_name VARCHAR2(20),
     logon_date timestamp,
     logoff_date timestamp);
    
    -- 创建登录触发器
    CREATE OR REPLACE TRIGGER logon_trigger
       AFTER LOGON ON DATABASE
    BEGIN
       INSERT INTO log_on_off_log (user_name, logon_date) VALUES (ora_login_user, systimestamp);
    END logon_trigger;
    
    -- 创建退出触发器
    CREATE OR REPLACE TRIGGER logoff_trigger
       BEFORE LOGOFF ON DATABASE
    BEGIN
       INSERT INTO log_on_off_log (user_name, logoff_date) VALUES (ora_login_user, systimestamp);
    END logoff_trigger;
    

     

    触发器简单介绍:

    触发器简要介绍:

    那正是说什么样找到触发器的数目?

    *  以sys.system_views*is表开头。让我们询问出数据库中采取触发器的音信。能够告诉您最近SQL Server版本中有哪些触发器。

    SELECT schema_name(schema_ID) '.'  name
    
      FROM sys.system_views WHERE name LIKE '%trigger%'
    
     ----------------------------------------
    
    sys.dm_exec_trigger_stats              
    
    sys.server_trigger_events              
    
    sys.server_triggers                    
    
    sys.trigger_event_types                
    
    sys.trigger_events                     
    
    sys.triggers                           
    
    
    
    (6 row(s) affected)
    

      个中sys.triggers看起来音信比较多,它又含有怎么着列?上面那几个查询很轻易查到:

     SELECT Thecol.name  ' '  Type_name(TheCol.system_type_id)
    
        CASE WHEN TheCol.is_nullable=1 THEN ' NULL' ELSE ' NOT NULL' END as Column_Information
    
    FROM sys.system_views AS TheView
    
      INNER JOIN sys.system_columns AS TheCol
    
        ON TheView.object_ID=TheCol.Object_ID
    
      WHERE  TheView.name = 'triggers'
    
      ORDER BY column_ID;
    

    结果如下:

     Column_Information
    
    ----------------------------------------
    
    name nvarchar NOT NULL
    
    object_id int NOT NULL
    
    parent_class tinyint NOT NULL
    
    parent_class_desc nvarchar NULL
    
    parent_id int NOT NULL
    
    type char NOT NULL
    
    type_desc nvarchar NULL
    
    create_date datetime NOT NULL
    
    modify_date datetime NOT NULL
    
    is_ms_shipped bit NOT NULL
    
    is_disabled bit NOT NULL
    
    is_not_for_replication bit NOT NULL
    
    is_instead_of_trigger bit NOT NULL
    

     

    故此我们多那几个音信有了更加好的敞亮,有了贰个索引的目录。这些定义有一些令人头晕,但是另一方面,它也是一对一简单的。大家能够意识到元数据,再找个查询中,要求做的便是改变那几个单词‘triggers’来寻觅你想要的视图名称。.

    在二〇一二会同以往版本,能够选取二个新的表值函数非常的大地简化上述查询,并可避防止各类连接。在底下的询问中,我们将追寻sys.triggers 视图 中的列。能够应用同样的询问通过改换字符串中的对象名称来取得别的视图的概念。

     SELECT name  ' '  system_type_name
    
        CASE WHEN is_nullable=1 THEN ' NULL' ELSE ' NOT NULL' END as Column_Information
    
    FROM sys.dm_exec_describe_first_result_set
    
      ( N'SELECT * FROM sys.triggers;', NULL, 0) AS f
    
      ORDER BY column_ordinal;
    

    询问结果如下:

     Column_Information
    
    ----------------------------------------
    
    name nvarchar(128) NOT NULL
    
    object_id int NOT NULL
    
    parent_class tinyint NOT NULL
    
    parent_class_desc nvarchar(60) NULL
    
    parent_id int NOT NULL
    
    type char(2) NOT NULL
    
    type_desc nvarchar(60) NULL
    
    create_date datetime NOT NULL
    
    modify_date datetime NOT NULL
    
    is_ms_shipped bit NOT NULL
    
    is_disabled bit NOT NULL
    
    is_not_for_replication bit NOT NULL
    
    is_instead_of_trigger bit NOT NULL
    

     

    sys.dm_exec_describe_first_result_set函数的最大优势在于你能见到其余结果的列,不止是表和视图、存款和储蓄进程大概贬值函数。

    为了查出任何列的音信,你能够动用稍微修改的版本,只需求改换代码中的字符串'sys.triggers'就能够,如下:

     Declare @TheParamater nvarchar(255)
    
    Select @TheParamater = 'sys.triggers'
    
    Select @TheParamater = 'SELECT * FROM '   @TheParamater
    
    SELECT
    
      name  ' '  system_type_name
    
        CASE WHEN is_nullable=1 THEN ' NULL' ELSE ' NOT NULL' END as Column_Information
    
    FROM sys.dm_exec_describe_first_result_set
    
      ( @TheParamater, NULL, 0) AS f
    
      ORDER BY column_ordinal;
    
    1. DML触发器, 表/视图级有效,可由DML语句 (INSERT, UPDATE, DELETE) 触发;

    2. DDL 触发器,数据库级有效,可由DDL语句 (CREATE, ALTEEnclave, DROP 等) 触发;

    3. LOGON 触发器, 实例级有效,可由用户账号登入(LOGON)数据库实例时接触;

    触发器是一种格外的储存进度,它的施行不是由程序调用,也不是手动实施,而是由事件来触发。触发器是当对某三个表打开操作。举个例子:update、insert、delete那些操作的时候,系统会自动调用推行该表上相应的触发器。

    触发器是一种特其他蕴藏进程,它的实施不是由程序调用,亦非手动实践,而是由事件来触发。触发器是当对某叁个表展开操作。比如:update、insert、delete这个操作的时候,系统会活动调用实践该表上相应的触发器。

    而是当然三个触发器是首先是贰个指标,由此一定在sys.objects?

      在我们接纳sys.triggers的消息以前,须要来再一次一遍,全体的数据库对象都存在于sys.objects中,在SQL Server 中的对象富含以下:聚合的CL瑞虎函数,check 约束,SQL标量函数,CL奥德赛标量函数,CLRAV4表值函数,SQL内联表值函数,内部表,SQL存储进程,CL智跑存款和储蓄进程,安排指南,主键约束,老式法规,复制过滤程序,系统基础表,同义词,种类对象,服务队列,CLCRUISERDML 触发器,SQL表值函数,表类型,用户自定义表,独一约束,视图和壮大存款和储蓄进程等。

      触发器是目的所以基础音信一定保存在sys.objects。不走运的是,有的时候大家须求十一分的音信,这么些音信能够通过目录视图查询。那么些额外数占有是何等呢?

     

      修改大家使用过的询问,来询问sys.triggers的列,本次我们会见到额外信息。那个额外列是来源于于sys.objects。

     SELECT coalesce(trigger_column.name,'NOT INCLUDED') AS In_Sys_Triggers,
    
           coalesce(object_column.name,'NOT INCLUDED') AS In_Sys_Objects
    
    FROM
    
     (SELECT Thecol.name
    
      FROM sys.system_views AS TheView
    
        INNER JOIN sys.system_columns AS TheCol
    
          ON TheView.object_ID=TheCol.Object_ID
    
      WHERE  TheView.name = 'triggers') trigger_column
    
    FULL OUTER JOIN
    
     (SELECT Thecol.name
    
      FROM sys.system_views AS TheView
    
        INNER JOIN sys.system_columns AS TheCol
    
          ON TheView.object_ID=TheCol.Object_ID
    
      WHERE  TheView.name = 'objects') object_column
    
    ON trigger_column.name=object_column.name
    
    查询结果:
    
    In_Sys_Triggers                In_Sys_Objects
    
    ------------------------------ ----------------------
    
    name                           name
    
    object_id                      object_id
    
    NOT INCLUDED                   principal_id
    
    NOT INCLUDED                   schema_id
    
    NOT INCLUDED                   parent_object_id
    
    type                           type
    
    type_desc                      type_desc
    
    create_date                    create_date
    
    modify_date                    modify_date
    
    is_ms_shipped                  is_ms_shipped
    
    NOT INCLUDED                   is_published
    
    NOT INCLUDED                   is_schema_published
    
    is_not_for_replication         NOT INCLUDED
    
    is_instead_of_trigger          NOT INCLUDED
    
    parent_id                      NOT INCLUDED
    
    is_disabled                    NOT INCLUDED
    
    parent_class                   NOT INCLUDED
    
    parent_class_desc              NOT INCLUDED
    

     

    以上那一个让大家知道在sys.triggers的附加消息,不过因为它一直是表的子对象,所以有些不相干音信是不会议及展览示在那几个内定的视图大概sys.triggers中的。以往将在带大家去承接找找那几个音讯。

     

    触发器分类:

    触发器分类:

    触发器的主题材料

      触发器是可行的,但是因为它们在SSMS对象资源管理器窗格中不是可知的,所以一般用来提示错误。触发器有时候会稍微微妙的地点让其出题目,譬喻,当导入进度中禁用了触发器,而且由于一些原因他们未有重启。

    下边是一个关于触发器的简便提示:

      触发器可以在视图,表恐怕服务器上,任何那几个目的上都足以有超越1个触发器。普通的DML触发器能被定义来实践代表一些数目修改(Insert,Update可能Delete)恐怕在数据修改未来施行。每叁个触发器与只与一个指标管理。DDL触发器与数据库关联也许被定义在服务器等第,那类触发器一般在Create,Alter可能Drop那类SQL语句实践后触发。

      像DML触发器同样,能够有四个DDL触发器被创制在同叁个T-SQL语句上。三个DDL触发器和言辞触发它的语句在同二个业务中运维,所以除了Alter DATABASE之外都能够被回滚。DDL触发器运维在T-SQL语句实行实现后,也正是无法同日而语Instead OF触发器使用。

      二种触发器都与事件相关,在DML触发器中,包罗INSERT, UPDATE, 和DELETE,可是无数风浪都能够与DDL触发器关联,稍后大家将掌握。

    一. DML触发器

    1、DML( 数据垄断(monopoly)语言 Data Manipulation Language)触发器:是指触发器在数据库中发生 DML 事件时将启用。DML事件是指在表或视图中对数码进行的 insert、update、delete 操作的讲话。

    1、DML( 数据操纵语言 Data Manipulation Language)触发器:是指触发器在数据库中发生 DML 事件时将启用。DML事件是指在表或视图中对数码进行的 insert、update、delete 操作的讲话。

    在数据库中列出触发器

    那正是说怎么获取触发器列表?上面小编在AdventureWorks数据库中进行查询,注意该库的视图中平昔不触发器。

    率先个查询全数新闻都在sys.triggers 的目录视图中。

    SELECT
    
      name AS TriggerName,
    
      coalesce(object_schema_name(parent_ID) '.'
    
         object_name(parent_ID),'Database (' db_name() ')') AS TheParent
    
    FROM sys.triggers;
    
    
    
    TriggerName                    TheParent
    
    ------------------------------ ----------------------------------------
    
    ddlDatabaseTriggerLog          Database (AdventureWorks2012)          
    
    dEmployee                      HumanResources.Employee                
    
    iuPerson                       Person.Person                          
    
    iPurchaseOrderDetail           Purchasing.PurchaseOrderDetail         
    
    uPurchaseOrderDetail           Purchasing.PurchaseOrderDetail         
    
    uPurchaseOrderHeader           Purchasing.PurchaseOrderHeader         
    
    iduSalesOrderDetail            Sales.SalesOrderDetail                 
    
    uSalesOrderHeader              Sales.SalesOrderHeader                 
    
    dVendor                        Purchasing.Vendor                      
    
    iWorkOrder                     Production.WorkOrder                   
    
    uWorkOrder                     Production.WorkOrder   
    

      小编利用元数据函数db_name()使SQL保持不难。db_name()告诉本身数据库的名称。object_schema_name()用来查询object_ID代表的指标的架构,以及object_name**()**查询对象名称。那几个对指标的援引指向触发器的持有者,触发器能够是数据库本人,也能够是表:服务器触发器有温馨的系统视图,稍后小编会议及展览示。

    只要想要看到有着触发器,那么大家最佳利用sys.objects 视图:

    SELECT name as TriggerName, object_schema_name(parent_object_ID) '.'
    
         object_name(parent_object_ID) AS TheParent
    
                FROM   sys.objects
    
               WHERE  OBJECTPROPERTYEX(object_id,'IsTrigger') = 1
    

     

    在意,输出不含有数据库等第的触发器,因为兼具的DML触发器都在sys.objects视图中,可是你会眼光浅短在sys.triggers视图中的触发器。

    地点查询结果:

    name                           TheParent
    
    ------------------------------ -------------------------------
    
    dEmployee                      HumanResources.Employee
    
    iuPerson                       Person.Person
    
    iPurchaseOrderDetail           Purchasing.PurchaseOrderDetail
    
    uPurchaseOrderDetail           Purchasing.PurchaseOrderDetail
    
    uPurchaseOrderHeader           Purchasing.PurchaseOrderHeader
    
    iduSalesOrderDetail            Sales.SalesOrderDetail
    
    uSalesOrderHeader              Sales.SalesOrderHeader
    
    dVendor                        Purchasing.Vendor
    
    iWorkOrder                     Production.WorkOrder
    
    uWorkOrder                     Production.WorkOrder
    

     

    1. 语句级触发器/行级触发器

    2、DDL(数据定义语言 Data Definition Language)触发器:是指当服务器或数据库中发生 DDL 事件时将启用。DDL事件是指在表或索引中的 create、alter、drop 操作语句。

    2、DDL(数据定义语言 Data Definition Language)触发器:是指当服务器或数据库中生出 DDL 事件时将启用。DDL事件是指在表或索引中的 create、alter、drop 操作语句。

    自家的表和视图有稍许个触发器?

    小编想清楚各样表有多少个触发器,并且什么动静下接触它们。下边大家列出了富有触发器的表以及各种事件的触发器数量。种种表或许视图对于触发器行为都有二个INSTEAD OF 触发器,或者是UPDATE, DELETE, 恐怕 INSERT

    。但是八个表可以有四个AFTE奥迪Q3触发器行为。这个将显得在底下的询问中(排除视图):

    SELECT
    
    convert(CHAR(32),coalesce(object_schema_name(parent_ID) '.'
    
         object_name(parent_ID),'Database (' db_name() ')')) AS 'Table', triggers,[KD1] [AC2] 
    
    convert(SMALLINT,objectpropertyex(parent_ID, N'TABLEDeleteTriggerCount')) AS 'Delete',
    
    convert(SMALLINT,objectpropertyex(parent_ID, N'TABLEInsertTriggerCount')) AS 'Insert',
    
    convert(SMALLINT,objectpropertyex(parent_ID, N'TABLEUpdateTriggerCount')) AS 'Update'
    
    FROM (SELECT count(*) AS triggers, parent_ID FROM sys.triggers
    
          WHERE objectpropertyex(parent_ID, N'IsTable') =1
    
             GROUP BY parent_ID
    
              )TablesOnly;
    
    --查询结果如下:
    
    Table                            triggers    Delete Insert Update
    
    -------------------------------- ----------- ------ ------ ------
    
    Purchasing.Vendor                1           0      0      0
    
    Production.WorkOrder             2           0      1      1
    
    Purchasing.PurchaseOrderDetail   2           0      1      1
    
    Purchasing.PurchaseOrderHeader   1           0      0      1
    
    Sales.SalesOrderDetail           1           1      1      1
    
    HumanResources.Employee          1           0      0      0
    
    Sales.SalesOrderHeader           1           0      0      1
    
    Person.Person                    1           0      1      1
    
    
    
    (8 row(s) affected)
    

    尽管超越一个触发器被触发在三个表上,它们不保证顺序,当然也能够动用sp_settriggerorder来支配顺序。通过应用objectpropertyex()元数据函数,要求依赖事件输入参数‘ExecIsLastDeleteTrigger’, ‘ExecIsLastInsertTrigger’ 或然‘ExecIsLastUpdateTrigger’来确认何人是终极多少个实行的触发器 。为了获得首个触发器,酌情采纳ObjectPropertyEx() 元数据函数,需求输入参数 ‘ExecIsFirstDeleteTrigger’, ‘ExecIsFirstInsertTrigger’ 大概 ‘ExecIsFirstUpdateTrigger’。

    于是我们未来精晓了表有如何触发器,哪些事件触发这一个触发器。能够应用objectpropertyex()元数据函数,那几个函数重回相当多两样新闻,依据钦点的参数分化。通过查阅MSDN中的文档,查看里面包车型大巴四个文书档案是不是有助于元数据查询,总是值得检查的。

    在SQL Server中,从概念来讲只有语句级触发器,但假设有行级的逻辑要拍卖,有多少个仅在触发器内一蹴而就的表 (inserted, deleted), 存放着受影响的行,能够从那多个表里抽取特定的行并自行定义脚本管理;

    3、登入触发器:是指当用户登陆 SQL SE本田UR-VVEEvoque实例建构会话时接触。如若身份验证战败,登入触发器不会触发。

    3、登录触发器:是指当用户登陆 SQL SE奥迪Q5VE君越实例创建会话时接触。借使身份验证退步,登陆触发器不会接触。

    触发器曾几何时触发事件?

    让大家看一下那一个触发器,DML触发器能够在具有其余时间产生后触发,不过能够在封锁被管理前同有的时候候触发INSTEAD OF触发动作。上边大家就来探视全数的触发的究竟是AFTEOdyssey 照旧INSTEAD OF 触发器,有事什么日子接触了触发器。

    /* 列出触发器,无论它们是否启用,以及触发器事件。*/
    
    SELECT
    
      convert(CHAR(25),name) AS triggerName,
    
      convert(CHAR(32),coalesce(object_schema_name(parent_ID) '.'
    
         object_name(parent_ID),'Database (' db_name() ')')) AS TheParent,
    
           is_disabled,
    
           CASE WHEN is_instead_of_trigger=1 THEN 'INSTEAD OF ' ELSE 'AFTER ' END
    
            Stuff (--get a list of events for each trigger
    
            (SELECT ', ' type_desc FROM sys.trigger_events te
    
               WHERE te.object_ID=sys.triggers.object_ID
    
             FOR XML PATH(''), TYPE).value('.', 'varchar(max)'),1,2,'') AS events
    
     FROM sys.triggers;
    

    结果如下:

    triggerName               TheParent                        is_disabled events
    
    ------------------------- -------------------------------- ----------- ---------
    
    ddlDatabaseTriggerLog     Database (AdventureWorks2012)    1           AFTER CREATE_TABLE, ALTER_TABLE, DROP_TABLE, CREATE_VIEW, ALTER_VIEW, DROP_VIEW, CREATE_INDEX, ALTER_INDEX, DROP_INDEX, CREATE_XML_INDEX, ALTER_FULLTEXT_INDEX, CREATE_FULLTEXT_INDEX, DROP_FULLTEXT_INDEX, CREATE_SPATIAL_INDEX, CREATE_STATISTICS, UPDATE_STAT
    
    t_AB                      dbo.AB                           0           INSTEAD OF INSERT
    
    dEmployee                 HumanResources.Employee          0           INSTEAD OF DELETE
    
    iuPerson                  Person.Person                    0           AFTER INSERT, UPDATE
    
    iPurchaseOrderDetail      Purchasing.PurchaseOrderDetail   0           AFTER INSERT
    
    uPurchaseOrderDetail      Purchasing.PurchaseOrderDetail   0           AFTER UPDATE
    
    uPurchaseOrderHeader      Purchasing.PurchaseOrderHeader   0           AFTER UPDATE
    
    iduSalesOrderDetail       Sales.SalesOrderDetail           0           AFTER INSERT, UPDATE, DELETE
    
    uSalesOrderHeader         Sales.SalesOrderHeader           0           AFTER UPDATE
    
    dVendor                   Purchasing.Vendor                0           INSTEAD OF DELETE
    
    iWorkOrder                Production.WorkOrder             0           AFTER INSERT
    
    uWorkOrder                Production.WorkOrder             0           AFTER UPDATE
    

     

    As you will notice, we used a FOR XML PATH(‘’) trick here to make a list of the events for each trigger to make it easier to read. These events were pulled from the sys.trigger_events view using a correlated subquery.

    留意到我们利用了FOR XML PATH(‘’)来列出事件的每个触发器,更便于读取通晓。sys.trigger_events应用相关子查询来查询这个事件。

    在ORACLE中, 对表做贰回DML操作产生贰遍接触,叫语句级触发器,别的仍是能够因而点名[FOR EACH ROW]子句,对于表中受影响的每行数据均触发,叫行级触发器,原有行用:OLD代表,新行用:NEW表示;

    里头 DML 触发器相比较常用,依据 DML 触发器触发的章程差别又分为以下二种意况:

    中间 DML 触发器相比常用,依照 DML 触发器触发的方法各异又分为以下三种情形:

    触发器的多少长度?

    广大数据库职员不接济冗长触发器的定义,但他们大概会开掘,依照定义的长短排序的触发器列表是研究数据库的一种有用艺术。

    SELECT convert(CHAR(32),coalesce(object_schema_name(t.object_ID) '.','')
    
         name) AS TheTrigger,
    
           convert(CHAR(32),coalesce(object_schema_name(parent_ID) '.'
    
         object_name(parent_ID),'Database (' db_name() ')')) AS theParent,
    
           len(definition) AS length --the length of the definition
    
    FROM sys.SQL_modules m
    
      INNER JOIN sys.triggers t
    
        ON t.object_ID=m.object_ID
    
    ORDER BY length DESC;
    

    访问sys.SQL_modules视图能够查看触发器定义的SQL DDL,并按大小顺类别出它们,最下面是最大的。

    结果:

    TheTrigger                       theParent                        length
    
    -------------------------------- -------------------------------- --------
    
    Sales.iduSalesOrderDetail        Sales.SalesOrderDetail           3666
    
    Sales.uSalesOrderHeader          Sales.SalesOrderHeader           2907
    
    Purchasing.uPurchaseOrderDetail  Purchasing.PurchaseOrderDetail   2657
    
    Purchasing.iPurchaseOrderDetail  Purchasing.PurchaseOrderDetail   1967
    
    Person.iuPerson                  Person.Person                    1498
    
    ddlDatabaseTriggerLog            Database (AdventureWorks2012)    1235
    
    Purchasing.dVendor               Purchasing.Vendor                1103
    
    Production.uWorkOrder            Production.WorkOrder             1103
    
    Purchasing.uPurchaseOrderHeader  Purchasing.PurchaseOrderHeader   1085
    
    Production.iWorkOrder            Production.WorkOrder             1011
    
    HumanResources.dEmployee         HumanResources.Employee          604
    

     

    好吧,小编或者太喝斥了,不太喜欢太长的,不过逻辑不时候会相当长。事实上,前三名以小编之见是离谱的,就算小编老是偏侧于尽恐怕少地利用触发器。

     

    after 触发器(之后触发):当中 after 触发器要求唯有实施insert、update、delete 某一操作之后触发器才会被触发,且只好定义在表上。

    after 触发器(之后触发):在那之中 after 触发器供给独有实践insert、update、delete 某一操作之后触发器才会被触发,且不得不定义在表上。

    这几个触发器访谈了多少对象

    在代码中,每一种触发器要拜会多少对象(比如表和函数)?

    我们只供给检查表明式正视项。那么些查询利用二个视图来列出“软”正视项(如触发器、视图和函数)。

    SELECT coalesce(object_schema_name(parent_id)
    
               '.','') convert(CHAR(32),name) AS TheTrigger,
    
              count(*) AS Dependencies
    
    FROM sys.triggers
    
    INNER JOIN sys.SQL_Expression_dependencies
    
    ON [referencing_id]=object_ID
    
    GROUP BY name, parent_id
    
    ORDER BY count(*) DESC;
    --结果:
    
    TheTrigger                               Dependencies
    
    ---------------------------------------- ------------
    
    Sales.iduSalesOrderDetail                7
    
    Sales.uSalesOrderHeader                  7
    
    Purchasing.iPurchaseOrderDetail          5
    
    Purchasing.uPurchaseOrderDetail          5
    
    Purchasing.uPurchaseOrderHeader          3
    
    Production.iWorkOrder                    3
    
    Production.uWorkOrder                    3
    
    dbo.t_AB                                 2
    
    Purchasing.dVendor                       2
    
    Person.iuPerson                          2
    
    ddlDatabaseTriggerLog                    1
    

     

    居然有多少个触发器有7个依附!让大家就Sales.iduSalesOrderDetail来其实看一下,有怎么着注重。

    2. BEFORE/AFTER/INSTEAD OF

    instead of 触发器 (以前接触):instead of 触发器并不执行其定义的操作(insert、update、delete)而仅是进行触发器本人。能够在表或视图上定义 instead of 触发器。

    instead of 触发器 (以前接触):instead of 触发器并不进行其定义的操作(insert、update、delete)而仅是实践触发器本人。能够在表或视图上定义 instead of 触发器。

    一定触发器访谈依然写入哪些对象?

    咱俩得以列出触发器在代码中引用的有所目的

    SELECT
    
      convert(char(32),name) as TheTrigger,
    
      convert(char(32),coalesce([referenced_server_name] '.','')
    
                 coalesce([referenced_database_name] '.','')
    
            coalesce([referenced_schema_name] '.','') [referenced_entity_name])
         as referencedObject
    
    FROM sys.triggers
    
    INNER JOIN sys.SQL_Expression_dependencies
    
    ON [referencing_id]=object_ID
    
    WHERE name LIKE 'iduSalesOrderDetail';
    
    --查询结果:
    
    TheTrigger                       referencedObject
    
    -------------------------------- --------------------------------
    
    iduSalesOrderDetail              Sales.Customer                 
    
    iduSalesOrderDetail              Person.Person                  
    
    iduSalesOrderDetail              Sales.SalesOrderDetail         
    
    iduSalesOrderDetail              Sales.SalesOrderHeader          
    
    iduSalesOrderDetail              Production.TransactionHistory  
    
    iduSalesOrderDetail              dbo.uspLogError                
    
    iduSalesOrderDetail              dbo.uspPrintError
    

     

    在SQL Server中,从概念来讲独有AFTEOdyssey/INSTEAD OF触发器,在表上支持AFTE智跑触发器,在表/视图上支撑INSTEAD OF触发器,对于BEFORE触发器的须要能够尝试通过INSEAD OF触发器来贯彻;

    DML 触发器有七个别具一格的表:插入表(instered)和删除表(deleted),这两张表是逻辑表。那三个表是白手起家在数据库服务器的内部存款和储蓄器中,并且两张表的都以只读的。这两张表的构造和触发器所在的数据表的协会是同一的。当触发器实现专门的学问后,这两张表就能够被删去。Inserted 表的数目是插入或是修改后的数码,而 deleted 表的数额是立异前的或是已去除的数额。

    DML 触发器有多个非凡的表:插入表(instered)和删除表(deleted),这两张表是逻辑表。这八个表是确立在数据库服务器的内部存款和储蓄器中,何况两张表的都以只读的。这两张表的构造和触发器所在的数据表的构造是同等的。当触发器实现工作后,这两张表就能被删去。Inserted 表的数额是插入或是修改后的多少,而 deleted 表的多少是翻新前的恐怕已去除的多寡。

    触发器里有怎样代码?

    未来让我们因此检查触发器的源代码来确认那点。.

    SELECT OBJECT_DEFINITION ( object_id('sales.iduSalesOrderDetail') ); 
    

    咱俩后面包车型客车查询是情有可原的,扫描源码可见全体的依赖性项。多量重视项表名对于数据库的重构等须求特别小心,举个例子,修改多少个基础表的列。

    据必要做哪些,您或者希望检查来自元数据视图的概念,并不是接纳OBJECT_DEFINITION函数。

     SELECT definition
    
    FROM sys.SQL_modules m
    
      INNER JOIN sys.triggers t
    
        ON t.object_ID=m.object_ID
    
    WHERE t.object_ID=object_id('sales.iduSalesOrderDetail');
    

    SQL Server DML Trigger

    BEFORE

    AFTER

    INSTEAD OF

    TABLE

    N/A

    VIEW

    N/A

    N/A

    1010cc时时彩经典版 1

    1010cc时时彩经典版 2

    探究触发器的代码

    There are always plenty of ways of using the metadata views and functions. I wonder if all these triggers are executing that uspPrintError procedure?

    有为数相当的多用到元数据视图和函数的方法。想知道是还是不是享有这个触发器都实行uspPrintError存储进程?

    /* 在富有触发器中搜寻字符串 */

     

    SELECT convert(CHAR(32),coalesce(object_schema_name(object_ID) '.','')
    
         name) AS TheTrigger, '...' substring(definition, hit-20,120)  '...'
    
    FROM
    
      (SELECT name, definition, t.object_ID, charindex('EXECUTE [dbo].[uspPrintError]',definition) AS hit
    
       FROM sys.SQL_modules m
    
         INNER JOIN sys.triggers t
    
           ON t.object_ID=m.object_ID)f
    
    WHERE hit>0; 
    

     

    结果如图:

    1010cc时时彩经典版 3

     

    8个援引正在执行那一个历程。大家在sys.SQL_modules中搜索了拥有的概念能够找到几个一定的字符串,这种艺术比一点也不快很暴力,可是它是卓有成效的!

    在ORACLE中,在表上帮忙BEFORE/AFTEENVISION触发器,在视图上协助INSTEAD OF触发器,比如ORACLE中无法直接对视图做DML操作,能够通过INSTEAD OF触发器来变样达成;

    AFTEGL450 触发器语法:

    AFTELacrosse 触发器语法:

    在装有目标中查找字符串

    自家想掌握除了触发器之外是或不是还会有其他对象调用那几个进度?大家有一点点修改查询以寻找sys.objects视图,而不是sys.triggers,以寻觅全部具备与之提到的代码的指标。大家还亟需展示对象的档期的顺序

    /* 在全体指标中检索字符串 */

     SELECT convert(CHAR(32),coalesce(object_schema_name(object_ID) '.','')
    
         object_name(object_ID)) AS TheObject, type_desc, '...' substring(definition,hit-20,120) '...' as TheExtract
    
    FROM
    
      (SELECT  type_desc, definition, o.object_ID, charindex('uspPrintError',definition) AS hit
    
       FROM sys.SQL_modules m
    
         INNER JOIN sys.objects o
    
           ON o.object_ID=m.object_ID)f
    
    WHERE hit>0; 
    

    查询结果如下图:

    1010cc时时彩经典版 4

     From this output we can see that, other than the procedure itself where it is defined, and the triggers, only dbo.uspLogError is executing the uspPrintError procedure. (see the first column, second line down)

    从那些输出中大家能够看出,除了在概念它的长河本人之外,还应该有触发器,独有dbo.uspLogError正在实行uspPrintError进程。(见第一列,第二行往下)

    ORACLE DML Trigger

    BEFORE

    AFTER

    INSTEAD OF

    TABLE

    N/A

    VIEW

    N/A

    N/A

     1 CREATE [ OR ALTER ] TRIGGER [ schema_name . ]trigger_name   
     2 ON { table }   
     3 [ WITH <dml_trigger_option> [ ,...n ] ]  
     4 { FOR | AFTER }   
     5 { [ INSERT ] [ , ] [ UPDATE ] [ , ] [ DELETE ] }   
     6 AS { sql_statement  [ ; ] [ ,...n ] }  
     7 
     8 <dml_trigger_option> ::=  
     9     [ NATIVE_COMPILATION ]  
    10     [ SCHEMABINDING ]  
    11     [ EXECUTE AS Clause ]
    
     1 CREATE [ OR ALTER ] TRIGGER [ schema_name . ]trigger_name   
     2 ON { table }   
     3 [ WITH <dml_trigger_option> [ ,...n ] ]  
     4 { FOR | AFTER }   
     5 { [ INSERT ] [ , ] [ UPDATE ] [ , ] [ DELETE ] }   
     6 AS { sql_statement  [ ; ] [ ,...n ] }  
     7 
     8 <dml_trigger_option> ::=  
     9     [ NATIVE_COMPILATION ]  
    10     [ SCHEMABINDING ]  
    11     [ EXECUTE AS Clause ]
    

    列出服务器级触发器及其定义

    笔者们能够透过系统视图理解它们啊?嗯,是的。以下是列出服务器触发器及其定义的言语

     SELECT name, definition
    
    FROM sys.server_SQL_modules m
    
      INNER JOIN sys.server_triggers t
    
    ON t.object_ID=m.object_ID; 
    

    在意,只好见到有权力看的触发器

     

    INSTEAD OF 触发器语法:

    INSTEAD OF 触发器语法:

    总结

      本文研讨过触发器,而且你能得知触发器,以及地下的主题材料。这里并不曾指向有关触发器的询问提供一个宏观的工具箱,因为笔者只是使用触发器作为示范来浮今后询问系统视图时也许行使的有的本事。在大家上学了目录、列和参数之后,大家将再次回到触发器,并打听了编辑访问系统视图和information schema视图的询问的一部分日常用途。表是元数据的多数地点的根基。它们是两种档案的次序的对象的父类,其余元数据如索引是表的性质。大家正在日渐地拼命去开掘全数有关表的新闻。期待上期

    3. 接触条件

     1 CREATE [ OR ALTER ] TRIGGER [ schema_name . ]trigger_name   
     2 ON { table | view }   
     3 [ WITH <dml_trigger_option> [ ,...n ] ]  
     4 { FOR | AFTER | INSTEAD OF }   
     5 { [ INSERT ] [ , ] [ UPDATE ] [ , ] [ DELETE ] }   
     6 [ WITH APPEND ]  
     7 [ NOT FOR REPLICATION ]   
     8 AS { sql_statement  [ ; ] [ ,...n ] | EXTERNAL NAME <method specifier [ ; ] > }  
     9 
    10 <dml_trigger_option> ::=  
    11     [ ENCRYPTION ]  
    12     [ EXECUTE AS Clause ]  
    13 
    14 <method_specifier> ::=  
    15     assembly_name.class_name.method_name  
    
     1 CREATE [ OR ALTER ] TRIGGER [ schema_name . ]trigger_name   
     2 ON { table | view }   
     3 [ WITH <dml_trigger_option> [ ,...n ] ]  
     4 { FOR | AFTER | INSTEAD OF }   
     5 { [ INSERT ] [ , ] [ UPDATE ] [ , ] [ DELETE ] }   
     6 [ WITH APPEND ]  
     7 [ NOT FOR REPLICATION ]   
     8 AS { sql_statement  [ ; ] [ ,...n ] | EXTERNAL NAME <method specifier [ ; ] > }  
     9 
    10 <dml_trigger_option> ::=  
    11     [ ENCRYPTION ]  
    12     [ EXECUTE AS Clause ]  
    13 
    14 <method_specifier> ::=  
    15     assembly_name.class_name.method_name  
    

    (1) 不能够接触的情事

    DDL 触发器语法:

    DDL 触发器语法:

    对此UPDATE,DELETE操作来说,均会接触触发器;而对于INSERT可能说IMPORT的气象,是足以调整不去接触的。

    1 CREATE [ OR ALTER ] TRIGGER trigger_name   
    2 ON { ALL SERVER | DATABASE }   
    3 [ WITH <ddl_trigger_option> [ ,...n ] ]  
    4 { FOR | AFTER } { event_type | event_group } [ ,...n ]  
    5 AS { sql_statement  [ ; ] [ ,...n ] | EXTERNAL NAME < method specifier >  [ ; ] }  
    6 
    7 <ddl_trigger_option> ::=  
    8     [ ENCRYPTION ]  
    9     [ EXECUTE AS Clause ]  
    
    1 CREATE [ OR ALTER ] TRIGGER trigger_name   
    2 ON { ALL SERVER | DATABASE }   
    3 [ WITH <ddl_trigger_option> [ ,...n ] ]  
    4 { FOR | AFTER } { event_type | event_group } [ ,...n ]  
    5 AS { sql_statement  [ ; ] [ ,...n ] | EXTERNAL NAME < method specifier >  [ ; ] }  
    6 
    7 <ddl_trigger_option> ::=  
    8     [ ENCRYPTION ]  
    9     [ EXECUTE AS Clause ]  
    

    本文由1010cc时时彩经典版发布于1010cc安卓版,转载请注明出处:1010cc时时彩经典版:Oracle数据库之PL,创建触发器

    关键词: