精华内容
下载资源
问答
  • AFTER触发器与INSTEAD OF触发器
    2021-01-19 17:58:04

    在对表进行操作时,总会产生 INSERTED 和(或)DELETED表,不管这个操作是否已经进行。这里的和/或,要看进行的什么操作,插入,产生 INSERTED 表,删除,产生DELETED表,而update则两个都会产生

    INSTEAD OF 触发器

    在本章第五节我们已经指出SQL Server 2000 支持AFTER 和INSTEAD OF 两种类型的触发器。其中INSTEAD OF 触发器是SQL Server 2000 的新添加的功能,AFTER 触发器等同于以前版本中的触发器。当为表或视图定义了针对某一操作(INSERT、 DELETE、 UPDATE) 的INSTEAD OF 类型触发器且执行了相应的操作时,尽管触发器被触发,但相应的操作并不被执行,而运行的仅是触发器SQL 语句本身。

    INSTEAD OF 触发器的主要优点是使不可被修改的视图能够支持修改。其中典型的例子是分割视图(partitioned view)。为了提高查询性能,分割视图通常是一个来自多个表的结果集,但是也正因此而不支持视图更新。下面的例子说明了如何使用INSTEAD OF触发器来支持对分割视图所引用的基本表的修改

    INSTEAD OF 触发器用来代替通常的触发动作,即当对表进行INSERT、UPDATE 或 DELETE 操作时,系统不是直接对表执行这些操作,而是把操作内容交给触发器,让触发器检查所进行的操作是否正确。如正确才进行相应的操作。因此,INSTEAD OF 触发器的动作要早于表的约束处理。

    INSTEAD OF 触发器的操作有点类似于完整性约束。在对数据库的操纵时,有些情况下使用约束可以达到更好的效果,而如果采用触发器,则能定义比完整性约束更加复杂的约束。有关触发器与约束的比较,请参见联机丛书。

    INSTEAD OF 触发器不仅可在表上定义,还可在带有一个或多个基表的视图上定义,但在作为级联引用完整性约束目标的表上限制应用。

    AFTER 触发器定义了对表执行了 INSERT、UPDATE 或 DELETE 语句操作之后再执行的操作。比如对某个表中的数据进行了更新操作后,要求立即对相关的表进行指定的操作,这时就可以采用 AFTER 触发器。AFTER 触发器只能在表上指定,且动作晚于约束处理。

    每一个表上只能创建一个 INSTEAD OF 触发器,但可以创建多个 AFTER 触发器。

    实例:

    INSTEAD OF 触发器:

    向表“计0261”插入数据时,检查学号是否存在于表“计026”中,如存在则进行插入操作,否则就不插入。

    SQL code

    AFTER 触发器:

    对订货表设置 AFTER(FOR) 类型的 INSERT 触发器,用来在插入记录时自动将统计值计算到订货统计表中。

    SQL code

    更多相关内容
  • 下面我摘录了SQL Server官方教程中的一段关于触发器的文字,确实有用的一点文字描述。 可以定义一个无论何时用INSERT语句向表中插入数据时都会执行的触发器。 当触发INSERT触发器时,新的数据行就会被插入到触发器...
  • 下面是具体解释:在带有复位端的D触发器中,当reset信号“复位”有效时,它可以直接驱动最后一级的与非门,令Q端“异步”置位为“1”or“0”。这就是异步复位。当这个复位信号release时,Q的输出由前一级的内部输出...

    异步复位信号亚稳态的原因:

    复位结束也就是释放的时刻恰在时钟上升沿的建立时间和保持时间之间时无法决定现在的复位状态是1还是0,造成亚稳态。

    下面是具体解释:

    在带有复位端的D触发器中,当reset信号“复位”有效时,它可以直接驱动最后一级的与非门,令Q端“异步”置位为“1”or“0”。这就是异步复位。当这个复位信号release时,Q的输出由前一级的内部输出决定。

    然而,由于复位信号不仅直接作用于最后一级门,而且也会做为前级电路的一个输入信号,因此这个前一级的内部输出也受到复位信号的影响。前一级的内部电路实际上是实现了一个“保持”的功能,即在时钟沿跳变附近锁住当时的输入值,使得在时钟变为高电平时不再受输入信号的影响。

    对于这一个“维持”电路,在时钟沿变化附近,如果“reset”信号有效,那么,就会锁存住“reset”的值;如果reset信号释放,那么这个“维持”电路会去锁当时的D输入端的数据。因此,如果reset信号的“释放”发生在靠时钟沿很近的时间点,那么这个“维持”电路就可能既没有足够时间“维持”住reset值,也没有足够时间“维持”住D输入端的值,因此造成亚稳态,并通过最后一级与非门传到Q端输出。如果reset信号的“释放”时间能够晚一点点,也就是说,让“维持”电路有足够的时间去锁住“reset”的值,那么,我们就可以肯定输出为稳定的“reset”状态了。这一小段锁住“reset”值所需要的时间,就是寄存器的removal time要求。

    如图第一个方框内是异步复位和同步释放电路。有两个D触发器构成。第一级D触发器的输入时VCC,第二级触发器输出是可以异步复位,同步释放后的复位信号。

    利用前面两级触发器实现。特点:

    第一级触发器的数据端口是接电源,即高电平1’b1。

    第一级触发器的输出,不能使用,因为仍存在亚稳态的危险。两级触发器做同步,是非总线信号的最常见异步处理方法。总线信号的异步处理方法,最常见的是异步fifo实现。

    很多人只知道触发器D端口来源是异步的话,会因为建立保持时间的时序违反而在触发器Q端口产生亚稳态。

    但是不清楚,异步复位信号为什么会导致亚稳态的产生。

    首先,回顾理论教材里介绍的建立保持时间违反分析,教材一般都是拿没有复位端口的D触发器举例。

    然后,画出带有异步复位端口的D触发器,下图带异步复位Rd,并带有异步置位端口Sd。

    由此得知,异步复位信号或者异步置位信号,跟数据端口D信号,没有什么区别,都会存在建立保持时间的违反,从而时序冲突,引发输出亚稳态。

    亚稳态,出现的问题或者麻烦,是在信号变化的时候,不能保证第一拍采样的值是固定的。

    如果信号稳定,不会出现亚稳态的。就是采样后的跳变,时刻不确定,也许早,也许晚。

    系统不希望这样的未知状态发生,系统希望知道在某一个时刻,后续逻辑需要的输入信号,是稳定值。

    二级触发器同步后,第二季触发器的输出基本上是稳定值。后续逻辑根据稳定值,会有稳定的行为。这就是追求的系统稳定性。

    最好是系统一起复位释放,但是时钟域不同,不可能保证系统一起复位释放。一般来说,系统复位释放的顺序,是需要保证的。否则系统就是不安全的。

    举个例子,系统启动时,内核读取启动指令,要powerdown某外设;但是powerdown的逻辑要求外设和内核没有通信请求正在发生。此时,外设比内核先释放复位的情况(复位释放的时刻,外设有可能已经开始与内核发生请求),与内核比外设先释放复位的情况(复位释放的时刻,外设肯定与内核没有发生请求),是不一样的,powerdown也许不能处理成功。

    这也是异步复位信号需要同步释放的原因,目的都是为了避免亚稳态的产生。

    第一级触发器的输出,永远存在亚稳态的可能。亚稳态,导致系统不会复位初始化到已知状态。

    当第一级触发器采样异步输入之后,允许输出出现的亚稳态可以长达一个周期,在这个周期内,亚稳态特性减弱。在第二个时钟沿到来时,第二级同步器采样,之后才把该信号传递到内部逻辑中去。第二级输出是稳定且已被同步了的。如果在第二级采样时保持时间不够,第一级的输出仍然处于很强的亚稳态,将会导致第二级同步器也进入亚稳态,但这种故障出现的概率比较小。

    一般情况下,两级同步器总体的故障概率是一级同步器故障概率的平方。在大部分的同步化设计中,两级同步器足以消除所有可能的亚稳态了。

    基本D触发器、同步D触发器和异步D触发器的Verilog描述

    //基本D触发器

    module D_EF(Q,D,CLK)

    input D,CLK;

    output Q;

    reg Q; //在always语句中被赋值的信号要声明为reg类型 寄存器定义

    always @ (posedge CLK) //上升沿,下降沿用negedge表示,^_^ 需要记忆

    begin Q 《= D; end

    endmodule

    //带异步清0、异步置1的D触发器

    module D_EF(q,qn,d,clk,set,reset)

    input d,clk,set,reset;

    output q,qn;

    reg q,qn;//寄存器定义

    always @ (posedge clk or negedge set or negedge reset)

    begin

    if(!reset) begin q《=0;qn《=1;end//异步清0,低有效

    else if(!set) begin q《=1;qn《=1;end //异步置1,低有效

    else begin q《=~d;qn《=~d;end

    end

    endmodule

    //带同步清0、同步置1的D触发器

    module D_EF(q,qn,d,clk,set,reset)

    input d,clk,set,reset;

    output q,qn;

    reg q,qn;

    always @ (posedge clk)

    begin

    if(reset) begin q《=0;qn《=1;end//同步清0,高有效

    else if(set) begin q《=1;qn《=1;end //同步置1,高有效

    else begin q《=~d;qn《=~d;end

    end

    endmodule

    打开APP阅读更多精彩内容

    点击阅读全文

    展开全文
  • 第十七章 使用触发器

    2021-04-06 07:51:36
    文章目录 第十七章 使用触发器定义触发器触发器的类型AFTER Triggers递归触发器Trigger Code%ok, %msg, and %oper 系统变量{fieldname}语法触发器代码中的宏`{name*O}`, `{name*N}`和`{name*C}`触发代码语法附加...

    第十七章 使用触发器

    本章介绍如何在Intersystems SQL中定义触发器。触发器是响应某些SQL事件执行的代码行。本章包括以下主题:

    定义触发器

    有几种方法可以为特定表定义触发器:

    • 在将投影到SQL表的持久性类定义中包含触发定义。例如,MyApp.person类的此定义包括Loggevent触发器的定义,在每个成功的数据插入到MyApp.person表之后,将在每个成功的数据插入后调用:
    Class MyApp.Person Extends %Persistent [DdlAllowed]
    {
        // ... Class Property Definitions
    
        Trigger LogEvent [ Event = INSERT, Time = AFTER ]
        {
            // Trigger code to log an event 
        }
     }
    
    • 使用SQL创建触发命令创建触发器。这在相应的持久性类中生成触发对象定义。 SQL触发器名称按照标识符命名约定进行操作。 IntersystemsIris®数据平台使用SQL触发名称生成相应的触发类实体名称。

    必须拥有%create_trigger管理级别权限来创建触发器。必须具有删除触发器的%drop_trigger管理级别权限。

    类的最大用户定义触发器数为200。

    注意:Intersystems Iris不支持收集投影的表上的触发。用户无法定义这样的触发器,并且作为子表的集合的投影不认为涉及该基本集合的触发。
    Intersystems Iris不支持修改Security.RolesSecurity.Users表的触发器。

    触发器的类型

    触发器由以下内容定义:

    • 导致它执行的事件类型。触发器可以是单个事件触发器或多事件触发。定义单个事件触发器以在指定表上发生插入,更新或删除事件时执行。定义多事件触发器以执行当在指定的表中发生多个指定的事件中的任何一个时执行。可以使用类定义或创建触发命令定义插入/更新,更新/删除或插入/更新/删除多事件触发器。事件类型在Class定义中指定了所需的事件触发器关键字。
    • 触发器执行的时间:在事件发生之前或之后。
      这是由可选的Time trigger关键字在类定义中指定的。
      默认为Before
    • 可以将多个触发器与同一事件和时间相关联;在这种情况下,可以使用order trigger关键字来控制触发多个触发器的顺序。先触发顺序较低的触发器。
      如果多个触发器具有相同的Order值,则不指定它们的触发顺序。
    • 可选的Foreach trigger关键字提供了额外的粒度。
      该关键字控制触发器是每一行触发一次(Foreach = row),还是每一行或对象访问触发一次(Foreach = row/object),还是每语句触发一次(Foreach = statement)。
      没有Foreach trigger关键字定义的触发器每一行触发一次。
      如果触发器是用Foreach = row/object定义的,那么触发器也会在对象访问期间的特定点被调用,如本章后面所述。
      可以使用INFORMATION.SCHEMA.TRIGGERSACTIONORIENTATION属性列出每个触发器的Foreach

    下面是可用的触发器及其等价的回调方法:

    • BEFORE INSERT (等价于 %OnBeforeSave())

    • AFTER INSERT (等价于 %OnAfterSave())

    • BEFORE UPDATE (等价于 %OnBeforeSave())

    • AFTER UPDATE (等价于 %OnAfterSave())

    • BEFORE UPDATE OF specified column(s)

    • AFTER UPDATE OF specified column(s)

    • BEFORE DELETE (等价于 %OnDelete())

    • AFTER DELETE (等价于 %OnAfterDelete())

    注意:当触发器执行时,它不能直接修改正在处理的表中的属性值。
    这是因为InterSystems IRIS在字段(属性)值验证代码之后执行触发代码。
    例如,触发器不能将LastModified字段设置为正在处理的行中的当前时间戳。
    但是,触发器代码可以对表中的字段值发出更新。
    更新执行自己的字段值验证。

    AFTER Triggers

    INSERTUPDATEDELETE事件发生后执行AFTER触发器:

    • 如果SQLCODE=0(事件成功完成),InterSystems IRIS将执行AFTER触发器。
    • 如果SQLCODE是负数(事件失败),系统间IRIS就不会执行AFTER触发器。
    • 如果SQLCODE=100(没有发现要插入、更新或删除的行),则系统间IRIS执行AFTER触发器。

    递归触发器

    触发器执行可以是递归的。
    例如,如果表T1有一个对表T2执行插入操作的触发器,表T2也有一个对表T1执行插入操作的触发器。
    当表T1有一个调用例程/过程的触发器,并且该例程/过程执行对T1的插入操作时,也可以发生递归。
    触发器递归的处理取决于触发器的类型:

    • 行和行/对象触发器:InterSystems IRIS不阻止行触发器和行/对象触发器递归地执行。
      处理触发器递归是程序员的责任。
      如果触发代码不处理递归执行,则可能发生runtime <FRAMESTACK>错误。
    • 语句触发器:InterSystems IRIS阻止AFTER语句触发器递归执行。
      如果InterSystems IRIS检测到该触发器在执行堆栈中已经被调用,它将不会发出AFTER触发器。
      没有错误发出;
      触发器不会被第二次执行。

    InterSystems IRIS不会阻止BEFORE语句触发器递归地执行。
    在触发递归之前处理是程序员的责任。
    如果BEFORE触发器代码不处理递归执行,可能会发生runtime <FRAMESTACK>错误。

    Trigger Code

    每个触发器包含执行触发操作的一行或多行代码。
    每当与触发器关联的事件发生时,SQL引擎就会调用这段代码。
    如果触发器是使用CREATE触发器定义的,则可以用ObjectScript或SQL编写此操作代码。
    (InterSystems IRIS将SQL编写的代码转换为类定义中的ObjectScript。)
    如果触发器是使用Studio定义的,那么这个操作代码必须用ObjectScript编写。

    因为触发器的代码不是作为过程生成的,所以触发器中的所有局部变量都是公共变量。
    这意味着触发器中的所有变量都应该用一个新语句显式声明;
    这可以防止它们与调用触发器的代码中的变量发生冲突。

    %ok, %msg, and %oper 系统变量

    • %ok:仅在触发器代码中使用的变量。
      如果触发代码成功,它设置%ok=1
      如果触发代码失败,它设置%ok=0
      如果在触发器执行期间发出SQLCODE错误,InterSystems IRIS将设置%ok=0
      %ok=0时,触发器代码中止,触发器操作和调用触发器的操作被回滚。
      如果插入或更新触发器代码失败,并且表中定义了一个外键约束,InterSystems IRIS将释放外键表中相应行上的锁。

    触发代码可以显式设置%ok=0
    这会创建一个运行时错误,中止触发器的执行并回滚操作。
    通常,在设置%ok=0之前,触发器代码显式地将%msg变量设置为用户指定的字符串,用于描述这个用户定义的触发器代码错误。

    %ok变量是一个必须显式更新的公共变量。
    在完成非触发代码SELECTINSERTUPDATEDELETE语句后,%ok的值与之前的值没有变化。
    %ok仅在执行触发器代码时定义。

    %msg:触发代码可以显式地将%msg变量设置为描述运行时错误原因的字符串。
    设置变量%msg

    %oper:仅在触发器代码中使用的变量。
    触发器代码可以引用变量%oper,该变量包含触发触发器的事件(插入、更新或删除)的名称。

    {fieldname}语法

    在触发器代码中,可以使用特殊的{fieldname}语法引用字段值(对于属于触发器关联的表的字段)。
    例如,下面是MyAppLogEvent触发器的定义。
    Person类包含一个对ID字段的引用,如{ID}:

    Class MyApp.Person Extends %Persistent [DdlAllowed]
    {
        // ... Definitions of other class members
    
        /// This trigger updates the LogTable after every insert
        Trigger LogEvent [ Event = INSERT, Time = AFTER ]
        {
            // get row id of inserted row
            NEW id,SQLCODE,%msg,%ok,%oper
            SET id = {ID}
    
            // INSERT value into Log table
            &sql(INSERT INTO LogTable 
                (TableName, IDValue) 
                VALUES ('MyApp.Person', :id))
            IF SQLCODE<0 {SET baderr="SQLCODE ERROR:"_SQLCODE_" "_%msg
                          SET %ok=0
                        RETURN baderr }
    
          }
       // ... Definitions of other class members
    
    }
    

    这个{fieldname}语法支持统一字段。
    它不支持%SerialObject集合属性。
    例如,如果表引用了嵌入的串行对象类Address(其中包含属性City),那么触发器语法{Address_City}就是对字段的有效引用。
    触发器语法{Address}是对集合属性的引用,不能使用。

    触发器代码中的宏

    触发器代码可以包含一个引用字段名的宏定义(使用{fieldname}语法)。
    但是,如果你的触发代码包含一个#Include预处理器指令,用于一个引用字段名的宏(使用{fieldname}语法),那么这个字段名就不能被访问。
    这是因为InterSystems IRIS在代码被传递给宏预处理器之前,翻译触发器代码中的{fieldname}引用。
    如果一个{fieldname}引用在#Include文件中,它不会在触发器代码中“看到”,因此不会被转换。

    这种情况的解决方法是定义一个带参数的宏,然后将{fieldname}传递给触发器中的宏。
    例如,#Include文件可以包含如下一行:

    #Define dtThrowTrigger(%val) SET x=$GET(%val,"?")
    

    然后在触发器中调用提供{fieldname}语法作为参数的宏:

      $$$dtThrowTrigger({%%ID})   
    

    {name*O}{name*N}{name*C}触发代码语法

    在更新触发器代码中有三种语法快捷方式可用。

    可以使用下面的语法引用旧的(预更新的)值:

    {fieldname*O}
    

    其中fieldname是字段的名称,星号后面的字符是字母“O”(表示旧)。
    对于插入触发器,{fieldname*O}总是空字符串("")

    你可以使用下面的语法来引用新的(更新后的)值:

    {fieldname*N}
    

    其中fieldname是字段的名称,星号后面的字符是字母“N”(表示新字段)。
    {fieldname*N}语法只能用于引用要存储的值;
    它不能用来更改值。
    不能在触发器代码中设置{fieldname*N}。
    在插入或更新时计算字段的值应该通过其他方法实现,比如SqlComputeOnChange

    可以使用以下语法测试字段值是否被更改(更新):

    {fieldname*C}
    

    其中,fieldname是字段的名称,星号后面的字符是字母“C”(表示已更改)。
    {fieldname*C}的计算结果是1,如果字段已经被修改,0,如果它没有被修改。
    对于插入触发器,InterSystems IRIS将{fieldname*C}设置为1。

    对于具有流属性的类,如果SQL语句(INSERTUPDATE)没有插入/更新流属性本身,则对流属性{stream *N}{stream *O}的SQL触发器引用将返回流的OID
    然而,如果SQL语句确实插入/更新了stream属性,{stream *O}仍然是OID,但{stream *N}的值被设置为以下之一:

    • 在触发器之前,将流字段的值以传递给更新或插入的任何格式返回。
      这可以是输入到stream属性中的文字数据值,也可以是临时stream对象的OREF或OID。
    • AFTER trigger将流的Id作为{stream *N}的值返回。
      这是InterSystems IRIS的Id值,存储在流字段名为global^classnameD中。
      该值根据流属性的CLASSNAME类型参数使用适当的Id格式。

    如果一个流属性使用InterSystems IRIS对象更新,{stream *N}的值总是一个OID

    注意:对于由串行对象的数组集合创建的子表触发器,触发器逻辑与对象访问/保存一起工作,但与SQL访问(插入或更新)不工作。

    附加触发器代码语法

    在ObjectScript中编写的触发器代码可以包含伪域引用变量{%%CLASSNAME}{%%CLASSNAMEQ}{%%OPERATION}{%%TABLENAME}{%%ID}
    这些伪字段在类编译时被转换成特定的值。

    可以从触发器代码、SQL计算代码和SQL映射定义中使用类方法,因为类方法不依赖于拥有开放对象。
    必须使用##class(classname). methodname()语法从触发器代码中调用方法。
    你不能使用..Methodname()语法,因为这个语法需要一个当前打开的对象。

    可以将当前行字段的值作为类方法的参数传递,但是类方法本身不能使用字段语法。

    Pulling Triggers

    如果调用对应于该表的DML命令,则“拉出”(执行)已定义的触发器。

    对于DML命令成功插入、更新或删除的每一行,都会拉取一行或行/对象触发器。

    对于每个成功执行的INSERTUPDATEDELETE语句,都会拉出一次语句触发器,而不管该语句是否实际更改了表数据中的任何行。

    • INSERT语句拉动相应的插入触发器。
      插入可以通过指定%NOTRIGGER关键字来阻止触发相应的触发器。
      指定%NOJOURN关键字的插入不会记录该插入或相应的插入触发器。
      这意味着插入事件或触发事件都不可能回滚。

    快速插入不能用于具有插入触发器的表。

    • UPDATE语句拉动相应的更新触发器。
      更新可以通过指定%NOTRIGGER关键字来阻止触发相应的触发器。
      指定%NOJOURN关键字的更新不会记录该更新或相应的更新触发器。
      这意味着更新事件或触发事件都不可能回滚。

    • 根据执行的DDL操作的类型,INSERTUPDATE语句拉动相应的INSERT触发器或UPDATE触发器。
      要防止触发任何类型的触发器,请指定%NOTRIGGER关键字。

    • DELETE语句拉动相应的DELETE触发器。
      DELETE可以通过指定%NOTRIGGER关键字来阻止触发相应的触发器。
      指定%NOJOURN关键字的删除不会记录删除或相应的删除触发器。
      这意味着删除事件或触发事件都不可能回滚。

    • TRUNCATE TABLE语句不会触发删除触发器。

    默认情况下,DDL语句和相应的触发操作被记录在日志中。
    %NOJOURN关键字阻止DDL命令和触发动作的日志记录。

    触发器和对象访问

    如果触发器是用Foreach = row/object定义的,那么触发器也会在对象访问期间的特定点被调用,这取决于触发器定义的EventTime关键字,如下所示:

    EventTime此时也调用Trigger
    INSERTBEFORE在新对象的%Save()之前
    INSERTAFTER在新对象的%Save()
    UPDATEBEFORE在已存在对象的%Save()之前
    UPDATEAFTER在已存在对象的%Save()
    DELETEBEFORE在现有对象的%DeleteId()之前
    DELETEAFTER在现有对象的%DeleteId()

    因此,也没有必要为了保持SQL和对象行为同步而实现回调方法,

    在对象访问期间没有拔出触发器

    默认情况下,SQL对象使用%Storage.Persistent存储。
    InterSystems IRIS也支持 %Storage.SQL storage
    SQL存储。

    在使用 %Storage.SQL storage的类中保存或删除对象时。
    SQL存储,所有语句(Foreach = statement)、行(Foreach = row)和行/对象(Foreach = row/object)触发器被拉出。
    没有定义Foreach trigger关键字的触发器是行触发器。
    提取所有触发器是默认行为。

    但是,在使用%Storage.SQL storage保存或删除类中的对象时。
    SQL,可以指定只有定义为Foreach = row/object的触发器应该被拉出。
    定义为Foreach = statementForeach = row的触发器不会被拉取。
    这是通过指定类参数OBJECTSPULLTRIGGERS = 0来实现的。
    默认值是OBJECTSPULLTRIGGERS = 1

    此参数仅应用于使用%Storage.SQL定义的类。

    触发器与事务

    触发器在事务中执行触发器码。它设置事务级别,然后执行触发器代码。成功完成触发器代码后,触发器提交事务。

    注意:使用事务的触发器的结果是,如果触发器调用提交事务的代码,则触发器的完成失败,因为事务级别已经递减为0.调用生产的业务服务时可能发生这种情况。

    使用INSERT语句级别对象触发器后,如果触发器集%OK = 0,则使用SQLCODE -131错误失败行的插入失败。如下所示,可能会发生交易回滚:

    • 如果auto_commit = on,则插入的事务将被回滚。
    • 如果auto_commit =off,则应用于回滚或提交输入的事务。
    • 如果使用no_auto_commit模式,则不启动事务,因此插入件不能回滚。

    Auto_Commit模式是使用 SET TRANSACTION %COMMITMODE optionSetOption()方法建立的,如下所示 SET status=$SYSTEM.SQL.Util.SetOption("AutoCommit",intval,.oldval). 可用方法INTVAL值为0(无),1(隐式)和2(显式)。

    触发器可以在触发器中的%MSG变量中设置错误消息。此消息将返回给呼叫者,给出触发器失败的信息。

    列出触发器

    在管理门户SQL接口目录详细信息中列出了为指定表定义的触发器。这列出了每个触发器的基本信息。

    Information.schema.triggers类列出了当前命名空间中的定义触发器。对于每个触发信息.Schema.triggers列出了各种属性,包括触发器的名称,关联的架构和表名称,EventManipulation属性(插入,更新,删除,插入/更新,ActionTiming属性(之前,之后),创建的属性(触发创建时间戳)和ActionStatement属性,它是生成的SQL触发器代码。

    创建的属性从上次修改课程定义时派生触发创建时间戳。因此,随后使用此类(例如,定义其他触发器)可能导致创建属性值的意外更新。

    可以从SQL查询中访问此信息.Schema.triggers信息,如下例所示:

    SELECT TABLE_NAME,TRIGGER_NAME,CREATED,EVENT_MANIPULATION,ACTION_TIMING,ACTION_ORIENTATION,ACTION_STATEMENT 
    FROM INFORMATION_SCHEMA.TRIGGERS WHERE TABLE_SCHEMA='SQLUser'
    

    在这里插入图片描述

    展开全文
  • 硬件语言描述 测试文件 仿真图 综合工具综合后的原理图 综合介绍D触发器 维基百科介绍: 其他来源(课本): 8位的D触发器 Verilog HDL程序设计 测试文件: 仿真波形: 综合工具综合后的电路: 内部电路...

    目录

    前言

    硬件语言描述

    测试文件

    仿真图

    综合工具综合后的原理图

    综合介绍D触发器

    维基百科介绍:

    其他来源(课本):

    8位的D触发器

    Verilog HDL程序设计

    测试文件:

    仿真波形:

    综合工具综合后的电路:

    内部电路图(Technology Schematic)为:


    前言

    D触发器虽然基础,但很重要,扎实地掌握对于硬件电路学习者必不可少,传统地认识D触发器的过程大概是给出电路图,分析电路图,写出真值表,然后硬件语言描述,功能仿真,用综合工具综合出电路。

    这对于直观的认识D触发器还是有点儿困难,个人觉得这种简单的电路,用Verilog HDL硬件语言描述可以直观地认识到它的功能,然后在观察其仿真波形,之后在用综合工具综合出相应的电路图来查看,再对其进行分析,会更符合至少是个人的认识规律。

    分析电路原理图虽然不难,但是这个过程还是很繁琐,这里不打算进行这种分析。

    下面直接给出1位D触发器的Verilog HDL硬件语言描述和测试文件;(包括异步清零和同步复位)

    硬件语言描述

    下面的硬件语言描述的是一个1为的D触发器,其功能为,当时钟上升沿到来时,输入信号d传输到输出端q,清零信号在always的敏感列表中,使得该触发器还具有异步清零的功能,rst为同步复位信号。

    //1位D触发器Verilog HDL程序代码
    
    module dff(clk,clr,rst,d,q);
    input clk;
    input clr,rst;
    input d;
    output q;
    reg q;
    
    always@(posedge clk or posedge clr)        //敏感源为时钟上升沿或清零信号的上升沿(异步清零)
    begin
    	if(clr == 1'b1)                          //清零信号有效时(高电平),输出清零
    		q <= 1'b0;
    	else if(rst == 1'b1)                    //复位信号有效时(高电平),输出置1(同步置1)
    		q <= 1'b1;
    	else                                    //二者都无效时,输出保持当前状态
    		q <= d;
    end
    
    endmodule
    

    测试文件

    `timescale 1ns/1ps
    module dff_tb;
    
    wire q;
    reg clk,clr,rst,d;
    
    //时钟信号
    always
    begin
    	# 10 clk = ~clk;
    end
    
    //初始化
    initial
    begin
    	clk = 1'b0;
    	clr = 1'b0;
    	rst = 1'b0;
    	d =1'b0;
    	#10 rst = 1'b1;            //10ns后复位信号有效,此刻应该输出置1
    	#10 clr = 1'b1; d = 1'b1;  //又过10ns,清零信号有效,且复位信号也继续有效,但清零信号优先级高,所以,此刻输出应该清零
    	#10 clr = 1'b0; rst = 1'b0; //又过了10ns,此刻复位和清零信号均无效,此刻输出应该保持当且输入的状态,也就是高电平
    	#20 d = 1'b0;
    	#20 d = 1'b1;
    
    end
    
    //实例化
    dff u1(.clk(clk), .clr(clr), .rst(rst), .d(d), .q(q));
    
    endmodule

    仿真图

    综合工具综合后的原理图

    简单的分析下这个电路,与rst相连的是一个二选一的选择器的选择端,当rst为1的时候,也就是高电平时候,选择Data1有效,此刻选择器的输出结果result为1,选择器的输出又接到D触发器的数据输入端,这就意味着时钟上升沿到来时,结果为1。这不就是说明rst高电平有效,有效时,置1。

    当rst为0时,选择器的输入Data0被选中作为D触发器的输入,这不就意味着rst无效时,D触发器的输出取决于输入信号的当前状态吗!

    当然,优先级别更高的是clr,也就是说当clr有效时,输出清零,而不管rst以及输入的值是什么。这点在硬件语言描述中有体现出来,这里综合出来的电路也体现出来了。


    综合介绍D触发器

    维基百科介绍:

    The D flip-flop captures the value of the D-input at a definite portion of the clock cycle (such as the rising edge of the clock). That captured value becomes the Q output. At other times, the output Q does not change.

    这段话来自于维基百科。来说说这句经典的话是什么意思吧。

    D触发器在时钟周期的某一部分(例如时钟的上升沿)捕获D输入的值。 捕获的值成为Q输出。 在其他时候,输出Q不会改变。

    它表达了一个十分普遍的意思,就是D触发器通常在时钟上升沿时,此刻会捕获D输入的值,然后保持这一值不变,直到下一个上升沿到来时,重新捕获D输入的值。


    其他来源(课本):

    在数字电路或数字系统中,触发器是时序逻辑电路用来存储1位二进制信息的基本单元电路,它靠双稳态电路来保存信息,具有存储记忆功能。触发器属于边沿敏感的存储器件,数据存储的动作由时钟信号的上升沿或下降沿进行同步。

    所存储的数值取决于时钟在其有效沿(上升沿或下降沿)发生跳变时数据输入端当时的数据,在其他所有时间上数据值及其跳变均被忽略,输出保持跳变沿时刻捕获的值。

    注意:

    D触发器是一种最简单的触发器,它在每个时钟的有效边沿存储输入端的当前值,该值与当前存储的数据值无关。虽然在clk的两个有效边沿之间的D数据的跳变,但是,在clk有效沿到来之前,D必须稳定足够的时间,否则器件可能工作不正常。



    8位的D触发器

    本想到此结束的,但还是附送一个礼包吧。

    上面仿真的是一个1位的D触发器,下面用硬件语言描述一个简单的8位D触发器,信号的输出q由clk的上升沿和输入信号d决定,当时钟上升沿到来时,输入端信号d传输到输出端q,不含清零和复位信号。(清零和复位信号,随便一加就好了,这里为了通用性不加了。)

    Verilog HDL程序设计

    //1位D触发器Verilog HDL程序代码
    
    module dff(clk,d,q);
    input clk;
    input[7:0] d;
    output[7:0] q;
    reg [7:0]q;
    
    always@(posedge clk)        //敏感源为时钟上升沿
    begin
    	q <= d;
    end
    
    endmodule
    

    测试文件:

    `timescale 1ns/1ps
    module dff_tb;
    
    wire[7:0] q;
    reg clk;
    reg[7:0] d;
    
    //时钟信号
    always
    begin
    	# 10 clk = ~clk;
    end
    
    //初始化
    initial
    begin
    	clk = 1'b0;
    	d =8'b00000000;
    	#10 d = 8'b00000011;
    	#10 d = 8'b00000000;
    	#10 d = 8'b00000111;
    	#40 d = 8'b00001111;
    
    end
    
    //实例化
    dff u1(.clk(clk), .d(d), .q(q));
    
    endmodule

    仿真波形:

    综合工具综合后的电路:

    内部电路图(Technology Schematic)为:

    可见,它是由8个1位的D触发器组成的。

    展开全文
  • MySQL触发器-条件触发器语法

    千次阅读 2021-01-18 23:04:17
    -Sun Yat-sen University 冯兴伟实验4 触发器(1)实验目的掌握数据库触发器的设计和使用方法(2)实验内容和要求定义BEFORE触发器和AFTER触发器。能够理解不同类型触发器的作用和执行原理,验证触发器的有效性。(3)...
  • 触发器

    2018-11-13 18:44:35
    一、触发器的主要优点 二、触发器支持的功能 三、触发器的类别 四、SQL Server中触发器的创建、删除和修改  4.1创建触发器的语句 4.2删除和修改触发器 4.3触发器中可使用的特殊表(inserted表和deleted表) ...
  • 在实际的数字系统中往往包含大量的存储单元,而且经常要求他们在同一时刻同步动作,为达到这个目的,在每个存储单元电路上引入一个时钟脉冲(CLK)作为控制信号,只有当CLK到来时电路才被“触发”而动作,并...下面附上
  • 上篇博文写了用仿真和综合来认识D触发器(通过仿真和综合认识D触发器(Verilog HDL语言描述D触发器)),这篇博文采用完全并行的方式来认识JK触发器。 让我们迅速进入正题吧。 J-K触发器的Verilog HDL程序代码 /...
  • Mysql触发器的定义和使用简要描述

    万次阅读 2018-03-14 18:44:42
    触发器(TRIGGER)是MySQL的数据库对象之一,从5.0.2版本开始支持。该对象与编程语言中的函数非常类似,都需要声明、执行等。但是触发器的执行不是由程序调用,也不是由手工启动,而是由事件来触发、激活从而实现...
  • 这个系列的博文已经写过了两篇,分别是通过仿真和综合认识D触发器(Verilog HDL语言描述D触发器)和通过仿真和综合认识JK触发器(Verilog HDL语言描述JK触发器),分析的方法是完全并行的。 这里再看一下T触发器。 ...
  • MonoBehaviour.OnTriggerStay(Collidercollider)//逗留触发器(持续触发); 3. 知识点补充 刚体使物体能在物理控制下运动。刚体可通过接受力与扭矩,使物体像现实方式一样运动。任何物体想要受重力影响,受...
  • 触发器实例讲解

    2021-11-25 21:39:48
    SQL触发器实例1 定义: 何为触发器?在SQL Server里面也就是对某一个表的一定的操作,触发某种条件,从而执行的一段程序。触发器是一个特殊的存储过程。 常见的触发器有三种:分别应用于Insert , Update , Delete ...
  • JavaScript触发器

    2019-11-10 19:06:15
    JavaScript触发器 一、功能 顾名思义就是操控鼠标或键盘触发(实现)一些特定功能。 二、功能实现 <script type="text/javascript"> var changeColor=function () { document.body.style....
  • 71 Zabbix自定义触发器

    2021-12-26 09:25:53
    一个触发器可以拥有下面几种状态: 值 描述 OK 这是一个正常的触发器状态。在旧版本的Zabbix中称为FALSE。 PROBLEM 通常意味着发生了某些事情。例如,处理器的负载较高。在旧版本的Zabbix中称为TRUE。...
  • Oracle触发器详细介绍

    2021-05-05 00:39:19
    行级触发器本章介绍行级触发器机制。大部分例子以INSERT出发器给出,行级触发器可从...下面在SQL*PLUS会话中创建和示例一个简单的Insert行级触发器。这个触发器调用DBMS_OUTPUT在每插入一行数据时打印“executing ...
  • 下面介绍d触发器的功能及作用。d触发器的原理是什么SD和RD接至基本RS触发器的输入端,它们分别是预置和清零端,低电平有效。当SD=1且RD=0时(SD的非为0,RD的非为1,即在两个控制端口分别从外部输入的电平值,原因是...
  • 钟控触发器

    千次阅读 2019-04-26 09:57:37
    其中电位式触发器结构最简单,前述的四种不同功能的触发器RS、D、JK、T,是按电位式触发器描述的。这里介绍其它结构形式的RS或D或JK或T触发器。1.电位式触发器的缺陷  电位式触发器在CP为高电平期间,能接收控制...
  • 触发器学习小结

    2020-12-10 14:36:49
    概述 与组合逻辑输出仅取决于输入不同...功能描述,按逻辑功能分类:RS、J-K、D、T 考虑上述电路,在上电后,Vin和Vout的值会取决于最初状态,为0或为1。之所以说该电路会具有一个稳态的值,考虑下面的情况: 若沿虚
  • sql 触发器未触发 SQL Triggers are another powerful database object we have at our disposal. In previous articles, we’ve covered user-defined functions, user-defined procedures, and SQL Views. Today...
  • zabbix-触发器详解

    2020-10-08 20:26:16
    一.Zabbix Trigger (触发器)概述 触发器用于定义item的报警阈值 触发器是“评估”由项目采集的数据并表示当前系统状况的逻辑表达式。 当监控项用于采集系统的数据时,始终遵循...一个触发器可以拥有下面几种状态:
  • 基本触发器和钟控触发器

    千次阅读 2019-07-22 22:27:03
    时序逻辑电路的一种就是触发器,我们这一章学4种触发器,分别是基本触发器,钟控触发器,主从触发器,边沿触发器。它们都是不断进化的。 基本触发器 基本触发器由两个与非门或者两个与或门交叉耦合组成,我们学习...
  • 在实际的数字系统中往往包含...把这种在时钟信号触发时才能动作的存储单元电路称为触发器,以区别没有时钟信号控制的锁存器。如前所述,***的设计方案,如采用格雷码计数器,同步电路等,可以**减少毛刺,但它并不能...
  • 0x00 触发器概述 组合逻辑电路:当前的输出只和当前的输入有关,只要知道当前的输出和输入的对应表(真值表),就可以写出逻辑函数表达式,进而将电路设计出来 时序逻辑电路: 输出不仅和当前的输入有关,还和...
  • MySql触发器介绍及应用
  • 下面是 JK触发器的 Verilog代码实现: module JK_FF( input wire Clk, input wire J, input wire K, output reg Q ); // 公式 always @(posedge Clk) begin Q <= (J&(~Q))|((~K)&Q); end // 查找...
  • 能够触发触发器事件的事件包括下面几种:DML事件DDL事件数据库事件DML事件触发器可以是语句或行级触发器。DML语句触发器在触发语句之前或之后触发DML行级触发器在语句影响的行变化之前或之后触发。用户可以给单一...
  • SQL|数据插入|触发器

    2021-08-22 16:23:03
    一次插入多条信息 ...&tqId=29802&rp=1&ru=/ta/sql&qru=/ta/sql/question-ranking 题目描述: 题目已经先执行了如下语句: drop table if exists actor; CREATE TABLE actor ( actor_id s
  • 基本概念:触发—时钟脉冲边沿作用下的状态刷新称为触发。...Qn+1触发器的功能描述功能表 ( 特性表、真值表)、状态图、特性方程(逻辑函数表达式)、时序图(波形图)触发器的电路结构与工作原理主从D触发器:1、电...
  • 总结触发器工作原理和特性

    万次阅读 2021-02-05 08:08:18
    基本概念:触发—时钟脉冲边沿作用下的状态刷新称为触发。...Qn+1触发器的功能描述功能表 ( 特性表、真值表)、状态图、特性方程(逻辑函数表达式)、时序图(波形图)触发器的电路结构与工作原理主从D触发器:1、电...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 34,746
精华内容 13,898
关键字:

下面关于触发器的描述