MySQL是最流行的关系型数据库管理系统,那么问题来了:什么是关系型数据库呢?还有其余类型数据库嘛?mysql
关系型数据库:数据结构是表,由二维表及其之间的联系组成的数据组织(MySQL、SQLServer)git
优势: (1)易于维护:都是使用表结构,格式统一; (2)使用方便:SQL语言通用,可用于复杂查询; (3)复杂操做:支持SQL,可用于一个表以及多个表之间很是复杂的查询 缺点: (1)读写性能比较差,尤为是海量数据的高效率读写; (2)固定的结构,灵活差; (3)高并发读写需求,关系型数据库对硬盘I/O是很大的瓶颈
非关系型数据库:严格上不是一种数据库,而是一种数据结构化存储方法的集合,也能够是文档或键值对等(Redis、MongoDB)github
优势: (1)格式灵活:存储数据的格式能够是key,value形式、文档形式、图片形式 (2)速度快:可使用硬盘或随机存储器做为载体,关系型只能使用硬盘 (3)高扩展性 (4)成本低:数据库部署简单,基本都是开源的 缺点: (1)不提供SQL支持,学习和使用成本较高 (2)无事务处理 (3)数据结构相对复杂,复杂查询性能
老生常谈,工欲善其事必先利其器!相对于windows系列的下一步下一步的安装,咱们着重看下Ubuntu环境下的MySQL安装与配置踩过的坑吧。sql
为何要先卸载呢?你能找到这篇文章,可能此刻的你已经在焦虑安装MySQL为何老不成功呢,那么先按下面卸载掉它;若是你是第一次安装MySQL的话,请忽略这一步的操做。数据库
# 先更新下Ubuntu的软件 sudo apt-get update # 删除 mysql-server sudo apt-get remove mysql-server # 删除和mysql相关的服务 sudo apt-get autoremove mysql-server # 删除 mysql-common sudo apt-get remove mmysql-common # 清除残留数据 dpkg -l | grep ^rc | awk '{print $2}' | sudo xargs dpkg -P
# 坑就在这里,记得以前安装的时候是会让输入用户名和密码的,但不知道怎滴就没了 sudo apt-get install mysql-server sudo apt-get install mysql-client sudo apt-get install libmysqlclient-dev # 查看MySQL服务是否安装成功 sudo netstat -tap | grep mysql
sudo vi /etc/mysql/mysql.conf.d ' # 将 bind-address=127.0.0.1 修改成 bind-address=0.0.0.0 # 也能够改为你指定终端的IP地址 bind-address=0.0.0.0 ' # 启动MySQL服务 sudo /etc/init.d/mysql restart # 重启MySQL服务 sudo /etc/init.d/mysql restart
$ sudo mysql -u root -p Enter password: # 直接就按Enter键就好了,由于在安装mysql-server的时候没有设置用户名和密码;虽然也能够操做数据库可是操做起来很是的不方便。 # 若是在数据库链接工具中链接该数据库就会报错:ERROR 1698 (28000): Access denied for user 'root'@'localhost' mysql> USE mysql; mysql> SELECT user, plugin FROM mysql.user; # 查询结果 +------------------+-----------------------+ | user | plugin | +------------------+-----------------------+ | root | mauth_socket | | mysql.session | mysql_native_password | | mysql.sys | mysql_native_password | | debian-sys-maint | mysql_native_password | | root | mysql_native_password | +------------------+-----------------------+ 5 rows in set (0.00 sec) # 结果发现root的plugin='auth_socket'并非本地密码,所以须要修改它 # 修改root帐户的密码和plugin的本地密码验证方式 mysql> UPDATE mysql.user SET authentication_string=PASSWORD('123'), plugin='mysql_native_password' WHERE user='root'; # 刷新 mysql> FLUSH PRIVILEGES; # 退出 mysql> exit; # 用再次登陆的时候就输入用户名密码就能够登陆成功了
mysql> SET GLOBAL validate_password_policy=0; mysql> SET GLOBAL validate_password_mixed_case_count=0; mysql> SET GLOBAL validate_password_number_count=3; mysql> SET GLOBAL validate_password_special_char_count=0; mysql> SET GLOBAL validate_password_length=3; mysql> UPDATE mysql.user SET authentication_string=PASSWORD('123'), plugin='mysql_native_password' WHERE user='root'; mysql> FLUSH PRIVILEGES; mysql> exit;
-- 解决密码问题:https://blog.csdn.net/qq_32799165/article/details/83574665 -- mysql -u root -h 127.0.0.1 -p GRANT ALL PRIVILEGES ON *.* TO 'root'@''IDENTIFIED BY 'rootpassword' WITH GRANT OPTION; FLUSH PRIVILEGES;
-- 用户管理特殊命令(PS:用户权限相关数据保存在mysql书库的user表中,不建议直接对其操做) -- 建立用户 CREATE USER '用户名'@'IP地址' IDENTIFIED BY '密码'; -- 删除用户 DROP USER '用户名'@'IP地址'; -- 修改用户 RENAME USER '用户名'@'IP地址' TO '新用户名'@'新IP地址'; -- 修改密码 SET PASSWORD FOR '用户名'@'IP地址' = PASSWORD('新密码'); -- -- 用户权限管理(默认权限什么都没有) -- 查看权限 SHOW GRANTS FOR '用户名'@'IP地址'; -- 受权 -- 权限[ ALL PRIVILEGES 除grant外的全部权限 -- SELECT 仅查权限 -- SELECT,INSERT 查和插入权限 -- ... -- USAGE 无访问权限 -- ALTER 使用alter table -- ALTER ROUTINE 使用alter procedure和drop procedure -- CREATE 使用create table -- CREATE ROUTINE 使用create procedure -- CREATE TEMPORARY TABLES 使用create temporary tables -- CREATE USER 使用create user、drop user、rename user和revoke all privileges -- CREATE VIEW 使用create view -- DELETE 使用delete -- DROP 使用drop table -- EXECUTE 使用call和存储过程 -- FILE 使用select into outfile 和 load data infile -- GRANT OPTION 使用grant 和 revoke -- INDEX 使用index -- INSERT 使用insert -- LOCK TABLES 使用lock table -- PROCESS 使用show full processlist -- SHOW DATABASES 使用show databases -- SHOW VIEW 使用show view -- UPDATE 使用update -- RELOAD 使用flush -- SHUTDOWN 使用mysqladmin shutdown(关闭MySQL) -- SUPER 使用change master、kill、logs、purge、master和set global。还容许mysqladmin调试登录 -- REPLICATION CLIENT 服务器位置的访问 -- REPLICATION SLAVE 由复制从属使用 -- ] GRANT INSERT(权限) ON '数据库'.'表' TO '用户'@'IP地址'; -- 取消权限 REVOKE INSERT(权限) ON '数据库'.'表' FROM '用户'@'IP地址'; -- [数据库.表: 数据库.* (数据库中的全部表)、 -- 数据库.存储过程 (指定数据库中的存储过程) -- 数据库.表 (指定数据库中的某张表) -- *.* (全部数据库) -- ] -- ['用户名'@'IP地址' (用户只能在该IP下才能访问) -- '用户名'@'192.168.1.%' (用户只能在改IP段下才能访问(通配符%表示任意)) -- '用户名'@'%' (用户能够再任意IP下访问(默认IP地址为%))
-- 启动免受权服务端 -- mysqld --skip-grant-tables -- 客户端 -- mysql -u root -p -- 修改用户名和密码 UPDATE mysql.user SET authentication_string=PASSWORD('password') WHERE user='root'; -- FLUSH PRIVILEGES;
【GitHub示例】windows
-- 显示数据库 SHOW DATABASES; -- 建立数据库 -- utf-8 编码格式的数据库 CREATE DATABASE databases_example DEFAULT CHARACTER SET utf8 COLLATE utf8_croatian_ci; -- gbk的数据库 CREATE DATABASE databases_example DEFAULT CHARACTER SET gbk COLLATE gbk_chinese_ci; -- 使用数据库 USE databases_example;
-- 使用表 USE databases_example; SHOW TABLES; -- 2.1 建立表 USE databases_example; CREATE TABLE IF NOT EXISTS user_info( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT '自增列', -- 设置为自增,插入数据时无需设置此列,默认将自增(表中只能有一个自增列) uid INT NOT NULL COMMENT '用户惟一的UID', -- 主键不容许有空值,单列它的值必须惟一,若是是多列,则其组合必须惟一 name VARCHAR(30) NOT NULL COMMENT '用户名', sex INT NOT NULL COMMENT '用户性别:0男;1女', -- 不能够为空 job VARCHAR(30) NULL COMMENT '用户职业', -- 能够为空 age VARCHAR(20) NOT NULL DEFAULT '请填写' COMMENT '用户年龄', -- 建立列时添加默认值,未指定默认值自动添加默认值 address TEXT NOT NULL COMMENT '通讯地址', detail TEXT NULL COMMENT '备注' )ENGINE=InnoDB DEFAULT CHARSET=utf8; USE databases_example; CREATE TABLE IF NOT EXISTS sex ( sex_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT '性别id', sex_name VARBINARY(10) NOT NULL COMMENT '实际性别' )ENGINE=InnoDB DEFAULT CHARSET=utf8; -- 2.2 删除表 -- TRUNCATE:快速清空数据表的所有数据,不会破坏表的结构 TRUNCATE TABLE databases_example.user_info; -- DELETE:删除表的指定数据 DELETE FROM databases_example.user_info WHERE id = '11'; -- DROP:删除表,清空数据并会删除表的结构 DROP TABLE databases_example.user_info; -- 2.3 修改表 -- 添加列 ALTER TABLE databases_example.user_info ADD add_col VARCHAR(20) COMMENT '表添加的列'; ALTER TABLE databases_example.user_info ADD add_col2 VARCHAR(20) COMMENT '修改表添加的列'; -- 删除列 ALTER TABLE databases_example.user_info DROP COLUMN add_col2; -- 修改列信息 ALTER TABLE databases_example.user_info MODIFY COLUMN add_col INT COMMENT '表修改的列'; ALTER TABLE databases_example.user_info CHANGE COLUMN add_col2 change_col INT COMMENT '修改列名和该列的类型'; -- 添加主键 ALTER TABLE databases_example.user_info ADD PRIMARY KEY(add_col); -- 删除主键 ALTER TABLE databases_example.user_info DROP PRIMARY KEY; ALTER TABLE databases_example.user_info MODIFY add_col INT, DROP PRIMARY KEY; -- 添加外键 ALTER TABLE '从表' ADD constraint '外键名称_FK_从表_主表' FOREIGN KEY '从表'('外键字段') REFERENCES '主表'('主键字段'); ALTER TABLE databases_example.user_info ADD constraint '外键名称_FK_从表_主表' FOREIGN KEY '从表'('外键字段') REFERENCES '主表'('主键字段'); -- 删除外键 ALTER TABLE databases_example.user_info DROP FOREIGN KEY '外键名称'; -- 修改默认值 ALTER TABLE databases_example.user_info ALTER add_col SET DEFAULT 1000; -- 删除默认值 ALTER TABLE databases_example.user_info ALTER add_col DROP DEFAULT;
-- 3. 数据类型 -- bit -- int -- bigint -- decimal -- float -- double -- char -- varchar -- text -- mediumtext -- longtext -- enum -- set -- DATE -- TIME -- YEAR -- DATETIME -- TIMESTAMP
【GitHub示例】bash
-- 基本语法:INSERT INTO table_name(clo1, clo2, ..., clon) VALUES(value1, value2, ..., valuen); INSERT INTO databases_example.user_info(uid, name, sex, job, age, address, detail, add_col, change_col) VALUES ('000011', '小A', 0, 'Programmer', 19, '北京朝阳酒仙桥', '喜欢睡觉', 20, 25), ('000012', '小B', 0, 'Programmer', 18, '北京朝阳酒仙桥', '喜欢睡觉', 20, 25), ('000013', '小B', 0, 'Programmer', 18, '北京朝阳酒仙桥', '喜欢睡觉', 20, 25);
-- 基本语法:DELETE FROM table_name; DELETE FROM databases_example.user_info WHERE id=1; TRUNCATE TABLE databases_example.sex; DROP TABLE databases_example.sex;
-- 基本语法:UPDATE table_name SET name='要修改内容' WHERE id=1; UPDATE databases_example.user_info SET name='AA' WHERE id=1;
-- 基本语法: SELECT * FROM databases_example.user_info WHERE id>1; -- 【条件】 SELECT * FROM databases_example.user_info WHERE id>1; SELECT * FROM databases_example.user_info WHERE id BETWEEN 2 AND 5; SELECT * FROM databases_example.user_info WHERE id IN(2, 4, 6); SELECT * FROM databases_example.user_info WHERE id NOT IN(2, 4, 6); SELECT * FROM databases_example.user_info WHERE id IN(SELECT uid FROM user_info ); -- 【通配符】 SELECT * FROM databases_example.user_info WHERE name LIKE '小%'; -- 开头的全部(多个字符串) SELECT * FROM databases_example.user_info WHERE name LIKE '小_'; -- ale开头的全部(一个字符) -- 【限制(分页)】 SELECT * FROM databases_example.user_info LIMIT 3; -- 前三行 SELECT * FROM databases_example.user_info LIMIT 4, 5; -- 从第4行开始后的5行 SELECT * FROM databases_example.user_info LIMIT 2 OFFSET 2; -- 从第2行开始后的1行 -- 【排序】 SELECT * FROM databases_example.user_info ORDER BY id ASC; -- 根据 “列” 从小到大排列 SELECT * FROM databases_example.user_info ORDER BY id DESC; -- 根据 “列” 从大到小排列 SELECT * FROM databases_example.user_info ORDER BY id DESC, uid ASC; -- 根据 “列1” 从大到小排列,若是相同则按列2从小到大排序 -- 【分组】 -- 特别的:group by 必须在where以后,order by以前 SELECT id FROM databases_example.user_info WHERE id > 1 GROUP BY age; -- 【连表】 -- 无对应关系则不显示 SELECT A.id, A.name, B.sex_name FROM databases_example.user_info AS A, databases_example.sex AS B WHERE A.nid = B.nid; -- 无对应关系则不显示 SELECT A.id, A.name, B.sex_name FROM databases_example.user_info AS A INNER JOIN databases_example.sex AS B ON A.id = B.sex_id; -- A表全部显示,若是B中无对应关系,则值为null SELECT A.id, A.name, B.sex_name FROM databases_example.user_info AS A LEFT JOIN databases_example.sex AS B ON A.id = B.sex_id; -- B表全部显示,若是B中无对应关系,则值为null SELECT A.id, A.name, B.sex_name FROM databases_example.user_info AS A RIGHT JOIN databases_example.sex AS B ON A.id = B.sex_id; -- 【组合】 -- 组合,自动处理重合 SELECT name FROM databases_example.user_info AS A UNION SELECT sex_name FROM databases_example.sex AS B; -- 组合,不处理重合 SELECT name FROM databases_example.user_info AS A UNION ALL SELECT sex_name FROM databases_example.sex AS B;
视图就是一张虚拟表(非真实存在),其本质是 sql 语句获取动态的数据集并为其命名,因为视图是虚拟表,没法对进行更新和删除,仅能作查询操做。【GitHub示例】服务器
-- 语法格式:CREATE VIEW '视图名称' AS 'SQL语句' CREATE VIEW user_id AS SELECT uid FROM databases_example.user_info;
-- 因为视图是虚拟表,没法对进行更新和删除,仅能作查询操做 SELECT * FROM databases_example.user_id;
-- 语法格式:DROP VIEW '视图名称' DROP VIEW databases_example.user_id;
-- 语法格式:ALTER VIEW '视图名称' AS 'SQL语句' ALTER VIEW databases_example.user_id AS SELECT * FROM databases_example.user_info;
对某个表进行【增/删/改】操做的先后若是但愿出发某个特定的行为时,可使用出发器;触发器用于定制用户对表进行【增/删/改】先后的行为。【GitHub示例】session
-- 格式:create trigger 触发器名 触发时间(BEFORE|AFTER) 触发事件 on 表名 for each now -- 触发器触发的具体事务 -- 执行过程为:执行触发事件做用在某个表上前或后,触发器执行具体的事物 DELIMITER // CREATE TRIGGER tri_before_insert_user_info BEFORE INSERT ON databases_example.user_info FOR EACH ROW BEGIN SELECT COUNT(*) INTO @num; END // DELIMITER ;
INSERT INTO databases_example.user_info(uid, name, sex, job, age, address, detail, add_col, change_col) VALUES('000016', '小C', 0, 'Programmer', 18, '北京朝阳酒仙桥', '喜欢睡觉', 20, 25); SELECT * FROM databases_example.user_info;
DROP TRIGGER tri_before_insert_user_info; INSERT INTO databases_example.user_info(uid, name, sex, job, age, address, detail, add_col, change_col) VALUES('000015', '小B', 0, 'Programmer', 18, '北京朝阳酒仙桥', '喜欢睡觉', 20, 25);
索引用于快速找出数据表中某一列中有一特定值的行。不使用索引,MySQL必须从第一条记录开始读完整个表,直到找出相关的行,表越大查询的时间相应就越长。索引的创建就是快速达到一个位置去搜索数据文件,而没必要查看全部数据,将会节省大量时间。数据结构
优势:(1)MySQL列类型均可以设置索引而且被索引; (2)大大加快数据的查询速度 缺点:(1)须要建立和维护耗费时间,随着数据量的增长所耗费的时间也会增长 (2)索引也须要占空间,索引文件有可能比数据文件都会大 (3)对表中数据进行增长、删除、修改时,索引也须要动态维护,下降了数据的维护速度。
【GitHub示例】
普通索引仅有一个功能:加速查询
-- 建立表的时候建立索引 USE databases_example; CREATE TABLE index_table( nid INT NOT NULL AUTO_INCREMENT PRIMARY KEY , name VARCHAR(20) NOT NULL , email VARCHAR(30) NOT NULL , -- 注意:对于建立索引时若是是 BLOB 和 TEXT 类型,必须指定length。 -- create index ix_extra on in1(extra(32)); INDEX ix_name(name) ); -- 令一种建立索引的方式 CREATE INDEX ix_nid ON index_table(nid); -- 删除索引 DROP INDEX ix_name ON index_table; -- 查看建立的索引 SHOW INDEX FROM databases_example.index_table;
惟一索引有两个功能:加速查询 和 惟一约束(可含NULL);也就是说表中只有一个索引,说明一下自增键也是索引的一种。
USE databases_example; CREATE TABLE unique_table( nid INT NOT NULL AUTO_INCREMENT , name VARCHAR(20) NOT NULL , email VARCHAR(20) NOT NULL , extra TEXT , UNIQUE ix_nid(nid) ); -- 另外一种建立惟一索引的方法 CREATE UNIQUE INDEX ix_nid ON databases_example.unique_table(nid) ; -- 查看建立的惟一索引 SHOW INDEX FROM databases_example.unique_table; -- 删除惟一索引 DROP INDEX ix_name ON databases_example.unique_table;
主键索引有两个功能:加速查询 和 惟一约束(不可含null)。
USE databases_example; CREATE TABLE primary_table( nid INT NOT NULL AUTO_INCREMENT , name VARCHAR(20) NOT NULL , email VARCHAR(30) NOT NULL , PRIMARY KEY (nid) , INDEX ix_nid(name) ); -- 查看建立的主键索引 SHOW INDEX FROM databases_example.primary_table; -- 另外一种建立方法 CREATE INDEX ix_name ON databases_example.primary_table(name); -- 删除主键索引 ALTER TABLE databases_example.primary_table DROP PRIMARY KEY; ALTER TABLE databases_example.primary_table MODIFY INT, DROP PRIMARY KEY;
组合索引时将n个列组合成一个索引,其应用场景为:频繁的同事使用n列来进行查询,如:WHERE n1 = 'ALEX' AND n2 = 666。
USE databases_example; CREATE TABLE mixture_table( nid INT NOT NULL AUTO_INCREMENT PRIMARY KEY , name VARCHAR(20) NOT NULL , email VARCHAR(20) NOT NULL ); -- 建立索引 CREATE INDEX ix_nid_name ON mixture_table(nid, name); -- 查看组合索引 SHOW INDEX FROM mixture_table; -- 删除组合索引 DROP INDEX ix_nid_name ON mixture_table;
【GitHub示例】
DELIMITER // CREATE FUNCTION f1( i1 INT, i2 INT ) RETURNS INT BEGIN DECLARE num INT; SET num = i1 + i2; RETURN(num); END // DELIMITER ;
SELECT f1(2,3) AS add_result;
DROP FUNCTION f1;
【GitHub示例】
-- 1.1 if语句 CREATE PROCEDURE pro_fi() BEGIN DECLARE i INT DEFAULT 0; IF i = 1 THEN SELECT i; ELSEIF i = 2 THEN SELECT 2; ELSE SELECT 22; END IF ; END ; CALL pro_fi();
-- 1.2 case语句 SELECT CASE WHEN uid = 11 THEN 'A' WHEN uid = 12 THEN 'B' WHEN uid = 13 THEN 'C' ELSE 'X' END AS 'test' FROM databases_example.user_info;
-- 2.1 while循环 USE databases_example; DELIMITER // CREATE PROCEDURE pro_while() BEGIN DECLARE num INT; SET num = 0; WHILE num < 100 DO SELECT num; SET num = num + 20; END WHILE; END // DELIMITER ; CALL pro_while();
USE databases_example; DELIMITER // CREATE PROCEDURE pro_repeat() BEGIN DECLARE i INT; SET i=0; REPEAT SELECT i; SET i = i + 1; UNTIL i<= 5 END REPEAT; END // DELIMITER ; CALL pro_repeat();
USE databases_example; DELIMITER // CREATE PROCEDURE pro_loop() BEGIN DECLARE i INT DEFAULT 0; loop_label: LOOP SET i = i +1; IF i < 8 THEN ITERATE loop_label; END IF; IF i >= 10 THEN LEAVE loop_label; END IF; SELECT i; END LOOP; END ; DELIMITER ; CALL pro_loop();
存储过程是一个SQL语句的集合,当主动去嗲用存储过程时,其中内部的SQL语句会按照逻辑执行。
【GitHub示例】
-- 1.1 无参数存储过程 DELIMITER // CREATE PROCEDURE pro_no_para() BEGIN SELECT * FROM databases_example.user_info; END // DELIMITER ; CALL pro_no_para(); -- 1.2 有参数存储过程 -- 对于存储过程可接受参数,其参数有三类: -- in 仅用于传入参数用 -- out 仅用于返回值用 -- inout 既能够传入又能够看成返回值 DELIMITER // CREATE PROCEDURE pro_para( IN i1 INT, IN i2 INT, INOUT i3 INT, OUT o1 INT ) BEGIN DECLARE temp1 INT; DECLARE temp2 INT DEFAULT 0; SET temp1 = 1; SET o1 = i1 + i2 + temp1 + temp2; SET i3 = i3 + 100; END // DELIMITER ; -- 执行有参数的存储过程(注意传参顺序传值的) SET @t1 = 4; SET @t2 = 5; CALL pro_para(1, 6, @t1, @t2); SELECT @t1, @t2;
DELIMITER // CREATE PROCEDURE pr4( IN n1 INT, INOUT n3 INT, OUT n2 INT ) BEGIN DECLARE temp1 INT; DECLARE temp2 INT DEFAULT 0; SELECT * FROM databases_example.user_info; SET n2 = n1 + 100; SET n3 = n3 + n1 +100; END // DELIMITER ; SET @t4 = 111; SET @t5 = 222; CALL pr4(100, @t4, @t5); SELECT @t4, @t5;
DROP PROCEDURE pro_no_para;
MySQL事务主要用于处理操做量大,复杂度高的数据。例如:在人员管理系统中删除一我的员,须要删除人员的基本资料,也要删除和该人员相关的信息,如信箱、文章等,这些数据库操做语句就构成了一个事务。
(1)原子性:一个事务中的全部操做,要么所有完成,要么所有不完成,不会结束在中间某个环节;事务在执行过程当中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务历来没有执行过同样 (2)一致性:在事务开始以前和事务结束之后,数据库的完整性没有被破坏。这表示写入的资料必须彻底符合全部的预设规则,这包含资料的精确度、串联性以及后续数据库能够自发性地完成预约的工做。 (3)隔离性:数据库容许多个并发事务同时对其数据进行读写和修改的能力,隔离性能够防止多个事务并发执行时因为交叉执行而致使数据的不一致。事务隔离分为不一样级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。 (4)持久性:事务处理结束后,对数据的修改就是永久的,即使系统故障也不会丢失。
【GitHub示例】
-- 1.建立事务 DELIMITER // CREATE PROCEDURE pro_transaction( OUT p_return_code tinyint ) BEGIN DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN -- ERROR SET p_return_code = 1; ROLLBACK ; END ; DECLARE EXIT HANDLER FOR SQLWARNING BEGIN -- warning SET p_return_code = 2; ROLLBACK ; END ; START TRANSACTION ; INSERT INTO databases_example.user_info(uid, name, sex, job, age, address, detail, add_col, change_col) VALUES('000015', '事务', 0, 'Programmer', 18, '北京朝阳酒仙桥', '喜欢睡觉', 20, 25); COMMIT ; -- success SET p_return_code = 0; END // DELIMITER ;
-- 2.执行事务 SET @i = 0; CALL pro_transaction(@i); SELECT @i;