• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

MySQL存储过程和触发器使用释疑_MySQL

mysql 搞代码 4年前 (2022-01-09) 30次浏览 已收录 0个评论
文章目录[隐藏]

测试表结构:

CREATE TABLE `a` (<br />    `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,<br />    `cnt` INT(11) NULL DEFAULT NULL,<br />    PRIMARY KEY (`id`)<br />)<br />COLLATE='utf8_general_ci'<br />ENGINE=MyISAM<br />ROW_FORMAT=DEFAULT

和存储过程相关的几个权限:

  alter routine,create routine,execute   

和触发器相关的权限:

  trigger  

创建一个测试账号:

grant select,update,insert,create,delete,trigger,alter routine,create routine,execute on test.* to 'mysqldba'@'%' identified <mark style="color:transparent">本文来源gaodaimacom搞#^代%!码&网*</mark>by '123456';

使用相关:

1.存储过程有定义者和调用者之说,触发器木有

我们可以为一个存储过程指明定义者和调用者,如果木有DEFINER,那默认就是创建者的环境,但是触发器不行,一旦创建了触发器,所有的用户执行的操作都会触发

例如:

DELIMITER $$<br /><br />DROP PROCEDURE IF EXISTS `test`.`p_test`$$<br /><br />CREATE DEFINER=`mysqldba`@`%` PROCEDURE `p_test`(in a int)<br />BEGIN<br />        select a;<br />END$$<br /><br />DELIMITER ;

只让mysqldba账号调用,但是如果具有更大权限的账号,如:root,也是可以调用的

2.触发器可以调用存储过程

3.触发器可以访问它自己表的新旧数据(通过old.colname,new.colname访问),也可以影响其他表,但是不允许修改已经被函数或者触发器使用(读或者写)的表,在MySQL5.0.10之前的版本,触发器不能修改其他表

4.MySQL5.0的版本,所有的触发器都是基于行(FOR EACH ROW)的,因为触发器通过insert,update,delete激活,MySQL5.0不支持FOR EACH STATEMENT,如:

DELIMITER $$<br /><br />DROP TRIGGER /*!50032 IF EXISTS */ `test`.`tai_a`$$<br /><br />CREATE<br />    /*!50017 DEFINER = 'mysqldba'@'%' */<br />    TRIGGER `tai_a` AFTER INSERT ON `a` <br />    FOR EACH ROW  -- MySQL 5.0只能这样,不能FOR EACH STATEMENT<br />    BEGIN<br />         insert into b values(NEW.id,NEW.cnt);            <br />    END;<br />$$<br /><br />DELIMITER ;

5.触发器可以通过UDF调用外部应用程序

详细可以参考:http://forge.mysql.com/projects/project.php?id=211

内部相关:

6.我们可以通过下面方式查看一个库下面的所有触发器:

SELECT TRIGGER_NAME, EVENT_MANIPULATION, EVENT_OBJECT_TABLE, ACTION_STATEMENT<br />FROM INFORMATION_SCHEMA.TRIGGERS<br />WHERE TRIGGER_SCHEMA='dbname';

7.触发器的存储形式

目前触发器存放在.TRG文件中,每一个表中的触发器存储在一个TRG文件中,我们可以到表的数据目录下,看到这个文件,如:

[root@sunss test]# ls<br />a.frm  a.MYD  a.MYI  a.TRG  b.frm  b.MYD  b.MYI  tai_a.TRN  tau_a.TRN  test.frm  test.MYD  test.MYI<br />[root@sunss test]# pwd<br />/home/mysql/test<br />[root@sunss test]# cat a.TRG <br />TYPE=TRIGGERS<br />triggers='CREATE DEFINER=`mysqldba`@`%` TRIGGER `tau_a` AFTER UPDATE ON `a` /n    FOR EACH ROW BEGIN/n            update b set cnt=NEW.cnt where id=NEW.id;/n    END' 'CREATE DEFINER=`mysqldba`@`%` TRIGGER `tai_a` AFTER INSERT ON `a` /n    FOR EACH ROW BEGIN/n         insert into b values(NEW.id,NEW.cnt);            /n    END'<br />sql_modes=0 0<br />definers='mysqldba@%' 'mysqldba@%'<br />client_cs_names='utf8' 'utf8'<br />connection_cl_names='utf8_general_ci' 'utf8_general_ci'<br />db_cl_names='utf8_general_ci' 'utf8_general_ci'<br />You have new mail in /var/spool/mail/root<br />[root@sunss test]#

8.触发器可以更新远程的表,但远程的表必须使用FEDERATED存储引擎

复制相关:

9.触发器在MySQL复制环境中也是可以工作的

在MySQL5.0的版本和其他大多数数据库系统一样,触发器和复制都能工作。在主库上,通过触发器承载的操作,不会复制到从库上。但是,如果主库上存在的触发器,如果在从库上的相关表中也创建的话,在从库上的触发器就能和主库一样被激活、触发。

10.在主库上的操作是怎样被复制到从库上去的?

首先要确定一件事:主从库都有同样的触发器,在主库上创建的触发器也要在从库上重新创建一遍。这样DML语句在复制中就能在从库上激活触发器。例如:还是a表,我们在a表中创建了一个after insert 触发器,复制过程如下:

1).一条insert语句插入a表

2).after insert 激活触发器,也插入到b表

3).insert语句写入到bin log中

4).复制线程获得并执行insert语句

5).after insert 激活触发器,也插入到b表

参考:MySQL手册存储过程和视图的权限控制


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:MySQL存储过程和触发器使用释疑_MySQL

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址