(多选题)以下关于触发器说法正确的有 ABCD
• A、
同一表不能创建两个相同触发时间、触发事件的触发程序(5.7.2版本之后可以)
• B、
不支持在视图上定义触发器
• C、
触发器中可以调用存储过程和存储函数
• D、
如果before触发器失败,则MySQL将不执行请求的操作
以下关于MySQL8.0触发器说法正确的有 ABD
A、
A. 触发器和存储过程之间的主要区别在于,当对表执行数据修改事件时,会自动调用触发器,而存储过程必须要明确地调用
B、
B. MySQL目前只支持FOR EACH ROW行级触发器,没有支持语句级触发器
C、
C. OLD列(旧值)不但可以引用,还可以修改
D、
D. 触发器执行的顺序是BEFORE触发器、表操作、AFTER触发器
以下哪些语句会触发表上的INSERT触发器? ABC
A、
A. INSERT
B、
B. REPLACE
C、
C. LOAD DATA
D、
D. UPDATE
下面关于游标的说法正确的是: ABD
A.利用基于变量的select into语句,仅能处理一条记录的数据。通过游标(或光标),能够对查询的结果集进行循环处理。
B.MySQL游标为只读,不可滚动和敏感。
C.游标只允许应用程序对查询语句select返回的行结果集中每一行进行相同的操作,而不能进行不同的操作。
D.游标必须在声明处理程序之前被声明,并且声明变量和条件之后。
下面关于触发器说法正确的是() ABCD
A、
A. 在INSERT触发程序中,仅能使用NEW.col_name,没有旧值。
B、
B. 在DELETE触发程序中,仅能使用OLD.col_name,没有新值。
C、
C. 在UPDATE触发程序中,可以使用OLD.col_name来引用更新前的旧值,也能使用NEW.col_name来引用更新后的行中的新值。
D、
D. 使用OLD和NEW关键字,能够访问受触发程序影响的行中的字段值。
UPDATE account a SET a.`STATUS` = '不活跃' WHERE DATE_ADD(a.LAST_ACTIVITY_DATE, INTERVAL 3 YEAR) < CURDATE();
正确答案:
DROP TRIGGER IF EXISTS d_newTransaction;
CREATE TRIGGER d_newTransaction AFTER INSERT ON acc_transaction FOR EACH ROW
BEGIN
UPDATE account a
SET a.`STATUS` = '正常'
WHERE a.ACCOUNT_ID = new.ACCOUNT_ID;
END;
update account a set a.STATUS = '不活跃'
where date_add(a.last_activity_Date, interval 3 year) < curdate();
select * from account;
select * from acc_transaction;drop trigger if exists d_newTransaction;
delimiter $$
create trigger d_newTransaction
after insert
on acc_transaction
for each row
begin
update account set account.STATUS = '正常'
where account.account_id = new.account_id;
end $$
delimiter ;insert into acc_transaction (TXN_ID, AMOUNT, TXN_DATE, TXN_TYPE_CD, ACCOUNT_ID, EXECUTION_BRANCH_ID, TELLER_EMP_ID)
values(28, 1, curdate(), 'CD', 1,1,1);
select * from account;
创建存储过程updateCloseDate,该存储过程更新account表中的关闭日期(CLOSE_DATE),根据产品编号做不同的更新操作,要求使用游标:
DROP PROCEDURE IF EXISTS updateCloseDate;
CREATE PROCEDURE updateCloseDate ()
BEGINDECLARE id INT;DECLARE type VARCHAR ( 255 );DECLARE opend DATE;DECLARE closed DATE;DECLARE bal DECIMAL ( 12, 4 );DECLARE cur CURSOR FOR SELECTa.ACCOUNT_ID,p.PRODUCT_TYPE_CD,a.OPEN_DATE,a.CLOSE_DATE,a.AVAIL_BALANCE FROMaccount a,product p WHEREa.PRODUCT_CD = p.PRODUCT_CD;DECLARE EXIT HANDLER FOR NOT FOUND CLOSE cur;OPEN cur;REPEATFETCH cur INTO id, type, opend, closed, bal;CASE type WHEN 'ACCOUNT' THENUPDATE account SET CLOSE_DATE = DATE_ADD(opend, INTERVAL IF (opend <= '2015-01-01', 20, 30)YEAR)WHERE ACCOUNT_ID = id;WHEN 'LOAN' THENUPDATE account SET CLOSE_DATE = DATE_ADD( opend, INTERVAL IF ( bal <= 100000, 20, 30 ) YEAR ) WHERE ACCOUNT_ID = id;WHEN 'INSURANCE' THENUPDATE account SET CLOSE_DATE = DATE_ADD( opend, INTERVAL 15 YEAR ) WHERE ACCOUNT_ID = id;END CASE;UNTIL 0 END REPEAT;CLOSE cur;END;CALL updateCloseDate ();SELECT a.ACCOUNT_ID, p.PRODUCT_TYPE_CD, a.OPEN_DATE, a.CLOSE_DATE, a.AVAIL_BALANCE
FROM account a, product p
WHERE a.PRODUCT_CD = p.PRODUCT_CD
ORDER BY a.ACCOUNT_ID;
drop procedure if exists updateCloseDate;
delimiter $$
create procedure updateCloseDate()
BEGINdeclare ab decimal(12,4);declare pc varchar(10);declare cd date;declare od date;declare ptc varchar(255);declare cur cursor for select avail_balance, product_cd, close_date, open_date, product_type_cdfrom account join product using(product_cd);DECLARE exit HANDLER FOR NOT FOUND CLOSE cur;open cur;repeatfetch cur into ab, pc, cd, od, ptc;update account set account.close_date = case when ptc = 'ACCOUNT'THEN case when od <= '2015-01-01'then open_date + interval 20 yearelse open_date + interval 30 yearend when ptc = 'LOAN'THEN case when ab <= 100000then open_date + interval 20 yearelse open_date + interval 30 yearend else close_date = open_date + interval 15 yearend ;until null end repeat;close cur;
END $$
delimiter ;
call updateCloseDate();select * from account;
在acc_transaction上定义触发器t_newTransaction,当往acc_transaction中插入一条数据时,依 据账户编号(ACCOUNT_ID)更新account表中对应账户的可用余额(AVAIL_BALANCE)和最后 活跃日期(LAST_ACTIVITY_DATE):
DROP TRIGGER IF EXISTS t_newTransaction;
CREATE TRIGGER t_newTransaction BEFORE INSERT ON acc_transaction FOR EACH ROW
BEGINDECLARE bal INT;IFnew.TXN_TYPE_CD = 'CW' OR new.TXN_TYPE_CD = 'TF' THENSELECT a.AVAIL_BALANCE INTO bal FROM account a WHERE a.ACCOUNT_ID = new.ACCOUNT_ID;IFbal < new.AMOUNT THEN DELETE FROM acc_transactionWHERE TXN_ID = new.TXN_ID; ELSE UPDATE account a SET a.AVAIL_BALANCE = a.AVAIL_BALANCE - new.AMOUNT, a.LAST_ACTIVITY_DATE = DATE(new.TXN_DATE) WHERE a.ACCOUNT_ID = new.ACCOUNT_ID; END IF; ELSE UPDATE account a SET a.AVAIL_BALANCE = a.AVAIL_BALANCE + new.AMOUNT, a.LAST_ACTIVITY_DATE = DATE(new.TXN_DATE) WHERE a.ACCOUNT_ID = new.ACCOUNT_ID; END IF;
END;
drop trigger t_newTransaction;
delimiter $$
create trigger t_newTransaction
after insert
on acc_transaction
for each row
beginupdate accountset account.avail_balance = casewhen (new.txn_type_cd = 'CD' or new.txn_type_cd = 'TT'or new.txn_type_cd = 'IC' or new.txn_type_cd = 'LI')then account.avail_balance + new.amountwhen (new.txn_type_cd = 'CW' or new.txn_type_cd = 'TF')then account.avail_balance - new.amountend where account.account_id = new.account_id;update account set account.last_activity_date =case when(account.avail_balance >= 0) then now()else account.last_activity_dateendwhere account.account_id = new.account_id;update account set avail_balance = case when(account.avail_balance < 0) then avail_balance + new.amountelse avail_balanceendwhere account.account_id = new.account_id;if (select avail_balance from account where account.account_id = new.account_id < 0)then delete from acc_Transactionwhere acc_Transaction.txn_id = new.txn_id;end if;
end$$
delimiter ;
新建teams表和players表
– Table structure for teams
DROP TABLE IF EXISTS teams;
CREATE TABLE teams(
id int NOT NULL,
name varchar(20) NOT NULL,
addres varchar(100) NOT NULL,
nums int NOT NULL,
PRIMARY KEY (id)
);INSERT INTO `teams` ( `id`, `name`, `addres`, `nums` )
VALUES( 1, '火箭', '休斯顿', 3 );
INSERT INTO `teams` ( `id`, `name`, `addres`, `nums` )
VALUES( 2, '湖人', '洛杉矶', 2 );
INSERT INTO `teams` ( `id`, `name`, `addres`, `nums` )
VALUES( 3, '勇士', '金洲', 1 );DROP TABLE IF EXISTS `players`;
CREATE TABLE `players` (
`id` int NOT NULL, `name` varchar(100) NOT NULL,
`team_id` int NOT NULL,
`salary` decimal(10,2) NOT NULL,
PRIMARY KEY (`id`)
);
请在players表中创建如下两个触发器:
insert into players VALUES(2,"科比",2,500000);
insert into players VALUES(3,"艾灵顿",2,100.0);
insert into players VALUES(4,"麦迪",1,30000.0);
insert into players VALUES(5,"姚明",1,30000.0);
insert into players VALUES(6,"沃尔",1,5000.0);
insert into players VALUES(7,"戈登",1,6000.0);
最后请运行查看结果: SELECT * FROM teams;
DROP TRIGGER IF EXISTS `before_inseret`;
CREATE TRIGGER `before_inseret` BEFORE INSERT ON `players` FOR EACH ROW
BEGINIFnew.salary < 10000 THENSET new.salary = 10 * new.salary;END IF;
END;2.
DROP TRIGGER IF EXISTS `insert_player`;
CREATE TRIGGER `insert_player` AFTER INSERT ON `players` FOR EACH ROW
BEGINUPDATE teams SET nums = nums + 1 WHERE teams.id = new.team_id;
END;
drop trigger BEFORE_INSERT_TRIGGER;
delimiter $$
create trigger BEFORE_INSERT_TRIGGER
BEFORE insert
on players
for each row
begin
if ( new.salary < 10000)then set new.salary = new.salary * 10;
end if;
end$$
delimiter ;drop trigger AFTER_INSERT_TRIGGER;
delimiter $$
create trigger AFTER_INSERT_TRIGGER
AFTER insert
on players
for each row
beginupdate teamsset teams.nums = teams.nums + 1;end$$
delimiter ;