当前位置: 澳门新濠3559 > 数据库 > 正文

而是执行触发后的语句,以后的相关版本中对M

时间:2019-10-06 19:48来源:数据库
始建触发器 是出格的积存进程,自动推行,平日不要有再次回到值 MySQL触发器 触发器(trigger):监视某种情形,并触及某种操作。 触发器创设语法四要素:1.蹲点地方(table) 2.监视事件

始建触发器 是出格的积存进程,自动推行,平日不要有再次回到值

MySQL触发器

触发器(trigger):监视某种情形,并触及某种操作。

触发器创设语法四要素:1.蹲点地方(table) 2.监视事件(insert/update/delete) 3.接触时间(after/before) 4.触发事件(insert/update/delete)

 

~~语法~~

CREATE TEscortIGGE中华V <触发器名称> --触发器必得盛名字,最多65个字符,恐怕后边会附有分隔符.它和MySQL中任何对象的命名格局为主相象.
{ BEFORE | AFTER } --触发器有试行的时间设置:能够设置为事件发生前或后。
{ INSERT | UPDATE | DELETE } --一样也能设定触发的风浪:它们得以在施行insert、update或delete的进程中触发。
ON <表名称> --触发器是属于某二个表的:当在那几个表上执行插入、 更新或删除操作的时候就产生触发器的激活. 我们不能给一样张表的同二个轩然大波布署多少个触发器。
FOR EACH ROW --触发器的施行间隔:FO奥德赛 EACH ROW子句公告触发器 每隔一行推行三遍动作,实际不是对总体表实行二次。
<触发器SQL语句> --触发器富含所要触发的SQL语句:这里的讲话能够是任何官方的话语, 包括复合语句,可是此地的语句受的限制和函数的一致。

 

create trigger triggerName

after/before insert/update/delete on 表名

for each row #那句话在mysql是固定的

begin

sql语句;

end;

注:各自颜色对应上边的四要素。

率先大家来创制两张表:

#商品表

create table g

(

  id int primary key auto_increment,

  name varchar(20),

  num int

);

#订单表

create table o

(

  oid int primary key auto_increment,

  gid int,

much int

);

insert into g(name,num) values('商品1',10),('商品2',10),('商品3',10);

 

假定大家在没动用触发器此前:即便大家前几天卖了3个商品1,大家需求做两件事

1.往订单表插入一条记下

insert into o(gid,much) values(1,3);

2.创新商品表商品1的剩余数量

update g set num=num-3 where id=1;

 

今昔,大家来创建一个触发器:

须要先推行该语句:delimiter $(意思是告诉mysql语句的终极换来以$甘休)

create trigger tg1
after insert on o
for each row
begin
update g set num=num-3 where id=1;
end$

此刻大家只要实践:

insert into o(gid,much) values(1,3)$

会发觉物品1的数额改为7了,表明在大家插入一条订单的时候,触发器自动帮我们做了更新操作。

 

但前几日会有贰个标题,因为大家触发器里面num和id都以写死的,所以无论我们买哪个商品,最后更新的都以商品1的数码。举个例子:大家往订单表再插入一条记下:insert into o(gid,much) values(2,3),实施完后会发掘货品1的多寡变4了,而商品2的多寡没变,那样鲜明不是大家想要的结果。我们必要修改大家事先创造的触发器。

我们怎么在触发器援用行的值,相当于说大家要拿走大家新插入的订单记录中的gid或much的值。

对于insert来说,新插入的行用new来表示,行中的每一列的值用new.列名来代表。

故此以往大家能够如此来改大家的触发器

create trigger tg2
after insert on o
for each row
begin
update g set num=num-new.much where id=new.gid;(注意此处和率先个触发器的分歧)
end$

其次个触发器创造实现,我们先把第贰个触发器删掉

drop trigger tg1$

再来测量试验一下,插入一条订单记录:insert into o(gid,much) values(2,3)$

实行完发掘商品2的数码改为7了,以后就对了。

 

明日还留存三种情景:

1.当顾客裁撤一个订单的时候,大家那边平昔删除二个订单,大家是否内需把相应的商品数量再加回去呢?

2.当客户修改一个订单的数量时,我们触发器修改怎么写?

我们先解析一下率先种状态:

蹲点地方:o表

蹲点事件:delete

接触时间:after

接触事件:update

对此delete来说:原来有一行,后来被去除,想征引被删去的这一行,用old来表示,old.列名能够征引被删除的行的值。

那大家的触发器就该那样写:

create trigger tg3

after delete on o

for each row

begin

update g set num = num old.much where id = old.gid;(注意那边的改动)

end$

创办实现。

再执行delete from o where oid = 2$

会发觉商品2的数目又形成10了。

 

其次种状态:

监视地方:o表

监视事件:update

接触时间:after

接触事件:update

对此update来讲:被涂改的行,修改前的多少,用old来表示,old.列名援引被改换以前行中的值;

修改的后的数码,用new来代表,new.列名引用被涂改以往行中的值。

那大家的触发器就该这样写:

create trigger tg4

after update on o

for each row

begin

update g set num = num old.much-new.much where id = old/new.gid;

end$

先把旧的数目苏醒再减去新的数码便是修改后的数额了。

我们来测验下:先把商品表和订单表的数据都清掉,易于测验。

假定大家往商品表插入八个商品,数量都是10,

买3个商品1:insert into o(gid,much) values(1,3)$

那儿商品1的多寡改为7;

咱俩再修改插入的订单记录: update o set much = 5 where oid = 1$

咱俩改为买5个商品1,那时候再查询商品表就能够发觉物品1的数据只剩5了,表明大家的触发器发挥成效了。

 

假如:要是商品表有商品1,数量是10;

咱俩往订单表插入一条记下:

insert into o(gid,much) values(1,20);

会意识商品1的多少产生-10了。那正是主题材料的随地,因为我们在此以前创设的触发器是after,也正是说触发的口舌是在插入订单记录之后才实践的,那样大家就不可能判定新插入订单的进货数码。

 

先讲一下after和before的区分:

after是先产生多少的增加和删除改,再接触,触发的说话晚于监视的增加和删除改操作,不能影响前边的增加和删除改造作;也正是说先插入订单记录,再立异商品的多寡;

before是先成功触发,再增加和删除改,触发的说话先于监视的增加和删除改,大家就有时机决断,修改就要产生的操作;

 

我们用三个卓绝案例来区分它们的区别,新建一个触发器:

#蹲点地方: 商品表o

#蹲点事件:insert

#接触时间:before

#接触事件:update

案例:当新增添一条订单记录时,判定订单的商品数量,假诺数额超越10,就暗中同意改为10

create trigger tg6

before insert on o

for each row

begin

  if new.much > 10 then

    set new.much = 10;

  end if;

  update g set num = num - new.much where id = new.gid;

end$

执行完,把前边创设的after触发器删掉,再来插入一条订单记录:

insert into o(gid,much) valus(1,20)$

奉行完会发现订单记录的数量改为10,商品1的数目变为0了,就不会现出负数了。

 

触发器(trigger):监视某种景况,并触及某种操作。 触发器创制语法四要素:1.监视地方(table) 2.蹲点事件(insert/update/delete) 3.触发...

认识触发器:

以下的稿子主要描述的是怎么样对MySQL触发器进行正确行使, MySQL数据库是在5.0 现在的连锁版本中对MySQL触发器进行援引,一时也足以用相关的触发器对数据的完整性进行保证。如本身有四个表ge_element。

 

       触发器是一种特有的存款和储蓄进程,它无法被展现的调用,而是在往表中插入记录,更动记录恐怕去除记录时,被机关激活。在触发器中能够查询任何表,也能够实践更复杂的T-SQL语句。若是施行的T-SQL语句实践了叁个违规操作,则足以经过回滚事务使语句不能够实施,并再次来到到业务实施前的图景,Microsoft SQL Server 允许为别的给定的 INSERT、UPDATEDELETE 语句创设七个触发器。

该表中有三个region_id,对应到ge_region表中的id,但是,region_id是足感觉空的,所以不应当安装外键约束,而本人在剔除ge_region表中的记录时,希望把在ge_element表中被引述到的记录的region_id设为0,因为没有数据库的外键约束,作者只得在程序中操作,但自笔者又不想透进程序来操作,因为引用region_id的表或许不只ge_element多个,那时,就大概用到MySQL触发器,在剔除ge_region表中的记录时,把被援用的表中的region_id设为0。

类型:

触发器的效劳:

1.创办触发器的口舌:

  1.后触发器 (AFTE卡宴,FO讴歌RDX)先实践对应语句,后实行触发器中的语句

◎触发器能够对数据库举行级联修改

CREATE T福特ExplorerIGGECRUISER <触发器名称> <--

  2.前触发器  并未当真的实行触发语句(insert,update,delete),而是举行触发后的口舌

◎触发器能够形成比CKECK约束更目迷五色的界定

{ BEFORE | AFTER }

  3.行级触发器 (FO凯雷德 EACH ROW) 在SQL server 中空头支票

◎触发器能够窥见改换前后表中数据的两样,并依靠那一个差异来开展对应的操作。

{ INSERT | UPDATE | DELETE }

 

◎对于三个表上的两样操作(INSERT,UPDATE可能DELETE)能够使用分歧的触发器,固然是对一样的讲话也足以调用差别的触发器达成不一致的操作。

ON <表名称>

商品号为1的仓库储存量:

◎完成一定的作业准绳。

FOR EACH ROW

澳门新濠3559 1

 

<触发器SQL语句>

 

 

触发器必得有名字,最多陆13个字符,大概后边会附有分隔符.它和MySQL中别的对象的命名格局为主相象.

1.后触发器(落成不相同表之间的封锁)


这里自个儿有个习于旧贯:就是用表的名字+'_'+触发器类型的缩写.因而只要是表t26,触发器是在事件UPDATE参照他事他说加以考察下边包车型地铁点2)和3))从前BEFORE)的,那么它的名字便是t26_bu。

 

语法:   CREATE TRIGGER trigger_name
ON { table | view }
[ WITH ENCRYPTION ]
{
    { { FOR | AFTER | INSTEAD OF } { [ INSERT ] [ , ] [ UPDATE ] }
        [ WITH APPEND ]
        [ NOT FOR REPLICATION ]
        AS
        [ { IF UPDATE ( column )
            [ { AND | OR } UPDATE ( column ) ]
                [ ...n ]
        | IF ( COLUMNS_UPDATED ( ) { bitwise_operator } updated_bitmask )
                { comparison_operator } column_bitmask [ ...n ]
        } ]
        sql_statement [ ...n ]
    }
}

能够直接在EMS中创建触发器。

--实现在销售量不大于库存量时,每卖出n件商品,对应商品的库存要减n,若销售量大于库存量,则回滚此次操作
IF EXISTS (SELECT *FROM sysobjects WHERE name='tr_SaleCommodity')
    DROP TRIGGER tr_SaleCommodity
GO
CREATE TRIGGER tr_SaleCommodity
ON OrderInfo FOR INSERT  --FOR/AFTER为后触发器
AS
    BEGIN
        IF EXISTS (
            SELECT  * FROM inserted I INNER JOIN CommodityInfo C ON I.CommodityId=C.CommodityId
            WHERE I.Amount>C.Amount
        )
            BEGIN
                ROLLBACK  --后触发器
                PRINT '商品的销售量大于商品的库存量'
            END    
        ELSE
            BEGIN
                UPDATE CommodityInfo
                SET Amount=Amount-(SELECT Amount FROM inserted)
                WHERE CommodityId IN
                (
                    SELECT CommodityId FROM inserted
                )
            END
    END
GO

2.接触时间:

执行:

AFTER
点名触发器独有在触发 SQL 语句中钦定的兼具操作都已经成功实施后才激起。全体的引用级联操作和束缚检查也亟须成功做到后,技艺实践此触发器。
例如仅钦点 FOPRADO 关键字,则 AFTECRUISER 是默许设置。
无法在视图上定义 AFTE奥迪Q3 触发器。
INSTEAD OF
点名施行触发器并非实行触发 SQL 语句,进而取代触发语句的操作。
在表或视图上,每种 INSERT、UPDATE 或 DELETE 语句最多能够定义多少个 INSTEAD OF 触发器。可是,能够在各个具备 INSTEAD OF 触发器的视图上定义视图。
INSTEAD OF 触发器不可能在 WITH CHECK OPTION 的可更新视图上定义。假使向钦定了 WITH CHECK OPTION 选项的可更新视图增多 INSTEAD OF 触发器,SQL Server 将爆发贰个谬误。客商必须用 ALTEOdyssey VIEW 删除该选项后才干定义 INSTEAD OF 触发器。
{ [DELETE] [,] [INSERT] [,] [UPDATE] }
是点名在表或视图上施行什么样数据修改语句时将激活触发器的要害字。必得最少钦命二个选项。在触发器定义中允许使用以自由顺序组合的那些首要字。如若钦赐的选项多于七个,需用逗号分隔那几个采纳。
对于 INSTEAD OF 触发器,不容许在全体 ON DELETE 级联操作援引关系的表上使用 DELETE 选项。同样,也分歧目的在于享有 ON UPDATE 级联操作援用关系的表上使用 UPDATE 选项。

Before表示在事变产生从前实行MySQL触发器,After表示在事变发生之后实施触发器;

INSERT INTO OrderInfo(UserId,CommodityId,Amount,PayMoney,PayWay,OrderTime,Confirm,SendGoods)
VALUES('YOUYOU',1,10,600,'网上银行','2014-11-11 00:00:00.000',1,1)

3.触发事件:

结果:

例1:

多个事件:insert, update, delete

澳门新濠3559 2

在Goods表中创制删除触发器,完成Goods表和Orders表中的级联删除。(注:这么些职能在SQLSEVEOdyssey3000此前只能用触发器达成)

4.触发器与表的关系:

  注意:1.上一行为发售记录,下一行为物品1的新闻

 

触发器是属于一个表的,当在这一个表上举行insert, update, delete操作时,就能促成相应的触发器被激活;

     2.卖出拾三个,仓库储存量由48变为38 

CREATE TRIGGER GoodsDelete
ON Goods    --在其上施行触发器

无法给同多个表的同一个操作创制五个不一样的触发器。

       3.能够看看以上的行销记录中的Paymoney是不科学的,它的值应该是Amount*OutPrice=10*300,所以须要前触发器来约束

AFTER DELETE
AS
DELETE FROM Orders
WHERE GoodsName IN
(SELECT Name FORM deleted)

5.触发间隔:

 


FOLX570 EACH ROW 子句布告MySQL触发器每隔一行实践三遍动作,并不是对整下表试行一次。

2.前触发器(能够兑现行反革命级触发器功能)

例2:在Orders表上树立贰个AFTELacrosse触发器,当向Orders表中插入一行(到场一条订单记录)时,检查订单中的货色是还是不是在整理中(查六柱预测应货色在Goods表中的状态是还是不是为1),借使在看护中,则不能够下订单。

6.触发的SQL语句:

 

CREATE TRIGGER OrderInsert
ON Orders
AFTER INSERT
AS
IF(SELECT Status FROM Goods,Insertd WHERE Goods.Name=inserted.Name)=1
BEGIN
   P奥迪Q3INT '货品正在整理中,无法在Orders表中增添该商品记录。'
   ROLLBACK TRANSACTION
END

触发器包涵所要触发的SQL语句:这里的讲话能够是其余合法的话语,满含复合语句,但是此间的语句受的范围和函数的完全一样。

--实现了日期校验和支付金额的计算
IF EXISTS(SELECT* FROM sysobjects WHERE name='tr_DateConfim')
    DROP TRIGGER tr_DateConfim
GO
CREATE TRIGGER tr_DateConfim
ON OrderInfo INSTEAD OF INSERT ,UPDATE
AS
    BEGIN
        DECLARE @date datetime
        SELECT @date=OrderTime FROM inserted
        IF @date BETWEEN '2012-1-1' AND '2015-1-1'
            BEGIN
                DECLARE @UserId varchar(20) ,@CommodityId int,@Amount int,@PayMoney money,@PayWay varchar(20),@OrderTime datetime,@Confirm int,@SendGoods int
                SELECT @UserId=UserId,@CommodityId=CommodityId,@Amount=Amount,@PayWay=PayWay,@OrderTime=OrderTime,@Confirm=Confirm,@SendGoods=SendGoods FROM inserted
                DECLARE @outPrice money
                SELECT @outPrice=OutPrice FROM CommodityInfo WHERE CommodityId=@CommodityId
                SET @PayMoney=@outPrice*@Amount
                PRINT 'inserted 中的数据:' CONVERT(varchar(20),@UserId) ' ' CONVERT(varchar(20),@CommodityId) ' ' CONVERT(varchar(20),@Amount) ' ' CONVERT(varchar(20),@PayMoney) ' ' CONVERT(varchar(20),@PayWay) ' ' CONVERT(varchar(20),@OrderTime) ' ' CONVERT(varchar(20),@Confirm) ' ' CONVERT(varchar(20),@SendGoods) ' ' CONVERT(varchar(20),@outPrice)
                INSERT INTO OrderInfo(UserId,CommodityId,Amount,PayMoney,PayWay,OrderTime,Confirm,SendGoods)
                SELECT UserId,CommodityId,Amount,@PayMoney,PayWay,OrderTime,Confirm,SendGoods FROM inserted
            END
        ELSE 
            PRINT '你插入的数据中的时间只能在 2012-1-1 到 2015-1-1 中间'
    END
GO

复合语句(BEGIN / END)是官方的.

执行:

例3:在Orders表上确立二个插入触发器,在加上三个订单时,减少Goods表相应货物记录的仓库储存量

流动调查节Flow-of-control)语句(IF, CASE, WHILE, LOOP, WHILE, REPEAT, LEAVE,ITERATE)也是合法的.

INSERT INTO OrderInfo(UserId,CommodityId,Amount,PayWay,OrderTime,Confirm,SendGoods)
VALUES('YOUYOU',1,5,'网上银行','2013-1-11',1,1)

CREATE TRIGGER OrdersInsert_1
ON Orders
AFTER INSERT
AS
UPDATE Goods SET Storage=Storage-inserted.Quantity
FROM Goods,inserted
WHERE Goods.Name=inserted.GoodsName

变量评释(DECLARE)以及派出(SET)是合法的.

   注意:这里插入时作者并未定义PayMoney,PayMoney是因此触发器来机关总计的

 

同意标准注脚.

结果:


丰硕管理评释也是允许的.

日子不得法:

例4 限定Orders表的订单日期(OrderDate)不能够手工修改。

而是在此处要记住函数有受限条件:不可能在函数中拜谒表.因而在函数中运用以下语句是不法的。

澳门新濠3559 3

CREATE TRIGGER OrderDataUpDat(e
ON Orders
AFTER UPDATE
IF UPDATE(OrderDate)
BEGIN
RAISESportageROLacrosse('不可能手动修改',10,1)
ROLLBACK TRANSACTION
END

7.创办触发器的权柄:

 

 

您不可能不要有相当大的权柄本事够成立MySQL触发器;作者在创建触发器的时候提醒要有super privilege技艺够成立;

日期准确:


MySQL数据库是在5.0 未来的相干版本中对MySQL触发器实行援引,一时也可以用相关...

打字与印刷音讯对应:@UserId ' ' @CommodityId ' ' @Amount ' ' @PayMoney ' ' @PayWay ' '@Order提姆e ' '@Confirm ' ' @SendGoods ' '@outPrice

例5:判定要插入的订单中的货色名称在Goods表中是或不是留存,假使空中楼阁则回滚事务.

澳门新濠3559 4

 

澳门新濠3559 5

CREATE TRIGGER OrderInsert_2
ON Orders
AFTER INSERT
AS
IF (SELECT COUNT(*) FORM Goods,inserted
WHERE Goods.Name=inserted.GoodName)=0
BEGIN
P奇骏INT('未有这种物品')
ROLLBACK TRAINSACTION
END

 


3.行级触发器(错误)

例6:INSTEAD OF触发器用于代替引起触发器实践的T-SQL语句。每当向SimpleCustomers视图实行INSERT语句时,Insertcustmer触发器被触发,那时Inserted表中早已有了要插入的数据,在Insertcustmer触发器的代码中,分析插入客商姓名的字符串,将其分拆为姓和名多少个字符串,并插入Customers表,而原先的INSERT语句无法进行。

  澳门新濠3559 6

创建SimpleCustomers视图

实行结果:

经过SimpleCustomers视图向Customers表中增添记录

澳门新濠3559 7

GO
CREATE VIEW SimpleCustomers(CustomerName,city,Tel)
AS
SELECT FistName ',' LastName,City,Tel
FROM Customers
GO
CREATE TIRGGER Insertcustmer
ON SimpleCustomers
INSTEAD OF INSERT
AS
DECLARE @Name varchar(40)
DECLARE @FistName varchar(20)
DECLARE @LastName varchar(20)
DECLARE @City varchar(20)
DECLARE @Tel varchar(20)
DECLARE @idx int
BEGIN
SELECT @Name=CustomerName,@City=City,@Tel=Tel
FROM inserted
SET @idx=CHARINDEX(',',@Name)
SET @FistName=LEFT(@Name,@idx-1)
SET @LastNme=RIGHT(@Name,@LEN(@Name)-@idx)
INSERT INTO Customers
(FistName,LastName,City,Tel)
VALUES(@FistName,@LastName,@City,@Tel)
END

能够看来在SQL server中并不补助行级触发器


编辑:数据库 本文来源:而是执行触发后的语句,以后的相关版本中对M

关键词: 澳门新濠3559