原创文章&经验总结&从校招到A厂一路阳光一路沧桑
执行存储过程
使用CALL子句执行存储过程,CALL子句接受存储过程的名称以及需要传递的参数。
CALL ordertotal(1,TRUE,@total);
SELECT @total;
如果存储过程中定义了OUT类型的输入参数,那么在执行存储过程时需要传入变量,如这里@total,并且变量都是用@开始的。如果存储过程中没有参数的话,就用空圆括号表示即可,CALL ordertotal();
删除存储过程
删除存储过程,可以使用DROP PROCEDURE子句。如DROP PROCEDURE ordertotal;
查询存储过程
显示创建一个存储过程的语句,可以使用SHOW CREATE PROCEDURE。如SHOW CREATE PROCEDURE ordertotal;
查询所有存储过程的状态,如果在定义存储过程中使用COMMENT添加注释,可以查看。同时可以LIKE进行过滤结果。如SHOW PROCEDURE STATUS LIKE '%order%';
6. 事务处理
什么是事务?
事务处理是用来维护数据库的完整性,它保证成批的MySQL操作要么完全执行,要么完全不执行。事务处理是一种机制,用来管理必须成批执行的MySQL操作,它们要么时作为整体执行或者完全不执行。
关键概念:
事务:是指一组SQL语句;
回退:是指撤销指定的SQL语句的过程;
提交:指将未存储的SQL语句的结果写入数据库表中;
保留点:指事务处理中设置的临时占位符,可以对它发布回退;
如何创建执行事务?
START TRANSACTION;
INSERT INTO customers (cust_name,item_price,item_quantity) VALUES ('1',5,18);
SELECT * FROM customers;
SAVEPOINT insertinto;
INSERT INTO customers (cust_name,item_price,item_quantity) VALUES ('2',5,18);
ROLLBACK TO insertinto;
执行结果为:插入数据('1',5,18)有效,因为,只会从保留点SAFEPOINT之后开始回退,也就是说保留点SAFEPOINT之前的SQL语句执行的结果仍然有效。
有这样一些细节:
STAET TRANSACTION用来表示下面的SQL语句集为一段事务;
SAFEPOINT 用于指定保留点insertinto;
ROLLBACK TO表示从指定保留点开=开始回退,也就是说保留点之前的SQL语句执行结果依然有效。如果仅仅使用ROLLBACK进行回退的话就表示从STAET TRANSACTION之后所有的SQL语句执行效果都会撤销;
MySQL提交(写或保存)操作是自动进行的,这称之为隐含提交。但是在事务处理块中,提交不会隐含进行,要使用COMMIT子句进行提交。如:
START TRANSACTION;
INSERT INTO customers (cust_name,item_price,item_quantity) VALUES ('1',5,18);
INSERT INTO customers (cust_name,item_price,item_quantity) VALUES ('2',5,18);
COMMIT;
采用COMMIT提交事务,如果两条SQL语句都执行成功,才会将数据都写入表中。
7. 触发器
什么是触发器?
当某条SQL语句发生时,自动执行某些其他的SQL语句的时候就需要使用到触发器。触发器只能响应:DELETE,INSERT,UPDATE这三个特定操作。
创建触发器?
创建触发器时需要给出最重要的四条信息:1.全局唯一的触发器名;2.触发器关联的表;3.触发器在何时执行(操作执行之前或者之后)4.触发器应该响应的活动(DELETE, INSERT或者UPDATE);
由于触发器只能响应特定的三种类型的操作,因此可创建的触发器也就三种类型:INSERT触发器,DELETE触发器以及UPDATE触发器。
> **INSERT触发器**
在执行INSERT触发器时,也这样几点需要注意:1.在INSERT触发器代码内,可以引用一个名为NEW的虚拟表,可以用NEW来访问刚插入的行数据;2.在BEFORE INSERT触发器中,NEW中的值可以被更新;3.对于AUTO_INCREMENT列,NEW在INSERT执行之前包含0.在INSERT执行之后包含新的自定生成值。
创建一个INSERT触发器,每次插入一行数据,每次会返回当前插入的行数据的id。
/*创建触发器*/
CREATE TRIGGER insertcustomers AFTER INSERT ON customers
FOR EACH ROW SELECT NEW.cust_id INTO @newinsertid;
/*执行触发器*/
INSERT INTO customers (cust_name,item_price,item_quantity) VALUES ('2',5,18);
SELECT @newinsertid;
有这样一些细节:
1. 使用CREATE TRIGGER来创建触发器;
2. AFTER INSERT表明在插入行数据之后,触发器才会执行特征操作;
3. FOR EACH ROW 表示对插入的每一行数据,触发器都起作用;
4. 针对INSERT触发器,可以使用虚拟表NEW,来使用刚插入的行数据。比如例子中,`SELECT NEW.cust_id INTO @newinsertid`表示将新插入的行数据的id赋值给变量@newinsertid;
> **DELETE触发器**
DELETE触发器在DELETE语句执行之前或者之后,需要知道以下两点:
1. 在DELETE触发器代码内,可以引用一个名为OLD的虚拟表,来访问被删除的行;
2. OLD表中的数据只能读,不能被更新,而在INSERT触发器中,就可以通过NEW来更新被插入的行数据;
例如,针对customers表,当删除一行数据时,返回被删除数据的`cust_id`以及`cust_name`:
/*创建DELETE触发器*/
DELIMITER //
CREATE TRIGGER insertcustomers AFTER DELETE ON customers
FOR EACH ROW
BEGIN
SELECT OLD.cust_name INTO @deletecustname;
SELECT OLD.cust_id INTO @deletecustid;
END //
/*调用DELETE触发器*/
DELETE FROM customers WHERE cust_id = 3;
SELECT @deletecustname;
SELECT @deletecustid;
基本上与创建INSERT触发器一样,只不过在DELETE触发器中只能使用OLD来访问被删除的行数据。
> **UPDATE触发器**
UPDATE触发器在UPDATE语句执行之前或者之后执行,需要知道一下几点:
1. 在BEFORE UPDATE触发器中可以使用NEW和OLD来访问数据,而在AFTER UPDATE触发器中使用NEW来访问数据会报错,只能使用OLD来访问数据;
2. 在BEFORE UPDATE触发器中,NEW中的值可以被改变,即允许更改将用于UPDATE的数据;
3. OLD中的行数据只能读,不能被更新;
一个UPDATE触发器示例如下:
/*创建UPDATE触发器*/
DELIMITER //
CREATE TRIGGER insertcustomers BEFORE UPDATE ON customers
FOR EACH ROW
BEGIN
SELECT NEW.cust_name INTO @beforeupdate;
SET NEW.cust_name = 'reset_name';
SELECT OLD.cust_name INTO @afterupdate;
END //
/*调用UPDATE触发器*/
UPDATE customers SET cust_name = 'happy' WHERE cust_id = 5;
SELECT @beforeupdate;
SELECT @afterupdate;
输出为@beforeupdate为‘happay’,而@afterupdate为'reset_name'。有这样一些细节:
1. NEW虚拟表中的数据可以更改,如这里采用 `SET NEW.cust_name = 'reset_name';`,将待更新的`cust_name由“happy”变成了“reset_name”`;
2. 在BEFORE UPDATE触发器中可以使用NEW和OLD来访问数据,而在AFTER UPDATE触发器中使用NEW来访问数据会报错;
删除触发器?
删除触发器,可以使用 DROP TRIGGER语句,比如DROP TRIGGER insertcustomers;。触发器不能更新或者覆盖,如果要修改触发器,必须删除这个触发器。