MySQL:视图、触发器、存储过程、事务
视图:
视图,虚拟表
创建虚拟表:
# 语法:
# create view 虚拟表名称 as 虚拟表;
create view course_and_teacher as select * from course inner join teacher on course.teacher_id = teacher.tid; # 虚拟表在硬盘上存储时,只有 表结构, 没有 表数据 那张表,即 只有 course_and_teacher.frm 这个文件;因为虚拟表的数据来自于其它表 # 创建的虚拟表可以直接使用:
select * from course_and_teacher;
# 每次使用 course_and_teacher 这张表时,都会触发 select * from course inner join teacher on course.teacher_id = teacher.tid; # 虚拟表不建议使用,因为 如果 你在数据库建了大量的视图,不利用扩展(数据库可能经常需要扩展;即强耦合);所以尽量用原生的 SQL # 另外,视图是用来查询的,不能用来修改(不要修改视图中的记录) # 修改视图:
# 语法: alert view 视图名称 as SQL语句;
alert view course_and_teacher as select * from course where cid>3; # 删除视图:
# 语法: drop view 视图名称;
drop view course_and_teacher;
触发器:
一碰就动;使用触发器可以定制用户对表 【增、删、改】操作时前后的行为(注意:没有查询)
# 一、创建触发器: # 针对 insert 可以是 before insert(对于每一行,在 insert 行为之前,去触发一个 begin.. end 之间的 SQL语句), 也可以是 after insert (对于每一行,在 insert 行为之后,去触发一个 begin.. end 之间的 SQL语句) # 语法(插入前):
# create trigger 触发器名称 before insert on 表名 for each row
# begin ... end # 插入前:
create trigger tri_before_insert_tb1 before insert on tb1 for each row
begin
...
end
# 插入后:
create trigger tri_after_insert_tb1 after insert on tb1 for each row
begin
...
end # 删除前:
create trigger tri_before_delete_tb1 before delete on tb1 for each row
begin
...
end
# 删除后:
create trigger tri_after_delete_tb1 after delete on tb1 for each row
begin
...
end # 更新前:
create trigger tri_before_update_tb1 before update on tb1 for each row
begin
...
end
# 更新后:
create trigger tri_after_update_tb1 after update on tb1 for each row
begin
...
end
示例:
# 准备表:
create table cmd(
id int primary key auto_increment,
user char(32), # 执行命令的用户
priv char(10), # 该用户的权限
cmd char(64), # 执行的命令
sub_time datetime, # 提交时间
success enum ('yes','no') # 0代表执行失败
); create table errlog( # 记录命令出错的表
id int primary key auto_increment,
err_cmd char(64), # 命令名
err_time datetime, # 错误命令的提交时间
); # 创建触发器
delimiter // # delimiter 用于声明 SQL语句的结束符 是 “//”,而不是 “;”
create trigger tri_after_insert_cmd after insert on cmd for each row
BEGIN
# 触发器提供了两个对象:NEW 和 OLD;NEW代表新增的记录,OLD代表以前老的记录(插入行为没有 OLD 一说,因为插入的永远都是 新的;修改的情况下,才有老的记录,同 NEW 也能派上用场)
if NEW.success = 'no' THEN # 等值判断只有一个等号; NEW.success 表示 NEW对象的 success 属性
insert into errlog(err_cmd,err_time) values(NEW.cmd,NEW.sub_time); # 必须加分号
end if; # 必须加分号
END// # 此处的 “//” 表示 触发器定义完了
delimiter ; # 重新声明 SQL语句 的结束符 为 “;” # NEW 表示即将插入的数据行,OLD 表示即将删除的数据行
# 触发器是 MySQL 的一个内置功能;我们也可以在 应用程序级别 自己去实现 触发器的功能,如利用 python 代码自己去实现 # 建议在 应用程序级别去实现 触发器的功能;方便以后扩展功能 # 使用触发器: 触发器无法由用户直接调用,而是由于对 表的 【增、删、改】 操作被动引发的
# 删除触发器:
drop trigger tri_after_insert_cmd;
# 查看触发器:
show triggers;
存储过程:
存储过程包含了一系列可执行的 sql语句,存储过程存放于MySQL中,通过调用它的名字可以执行其内部的一堆 sql
优点:
1. 用于替代程序写的SQL语句,实现程序与sql解耦
2. 基于网络传输,传别名的数据量小,而直接传sql数据量大
缺点:
程序扩展功能不方便
示例:
# 调用存储过程
# MySQL中调用:
call p1(); # python中调用:
cursor.callproc('p1') # 用 cursor 去调用 callproc('存储过程的名称') 方法
# 如果 存储过程中是查询语句,利用相应的方法去获取相应的结果:
print(cursor.fetchall()) # 有参
delimiter //
create procedure p2(in n1 int,in n2 int,out res int) # 1. MySQL中的存储过程,参数必须指定 参数类型;2. 参数必须指明是用来接收值的,还是用来返回值的:in 代表传入参数, out表示返回参数,inout表示可进可出
BEGIN
select * from db7.student where tid>n1 and tid<n2;
set res = 1; # set 设置返回值
END //
delimiter ;
# MySQL 中调用:
set @x=0 # 设置变量的初始值
call p2(2,5,@x); # 传参
select @x; # 查看 返回值
# python 中调用:
cursor.callproc('p2',(2,5,0)) # callproc 在执行该存储过程的时候会把参数做转换: @_p2_0=2, @_p2_1=5, @_p2_2=0
# 如果 存储过程中是查询语句,利用相应的方法去获取相应的结果:
print(cursor.fetchall())
# 查看返回结果
cursor.execute('select @_p2_2')
print(cursor.fetchone())
应用程序与数据库结合使用的三种方式:
方式一:
MySQL:编写存储过程
Python:调用存储过程 方式二:
Python:编写纯生SQL
MySQL:啥也不干 方式三:
Python:ORM
MySQL:啥也不干
事务:
事务用于将某些操作的多个SQL作为原子性操作,一旦有某一个出现错误,即可回滚到原来的状态,从而保证数据库数据完整性
示例:
# 建表
create table user(
id int primary key auto_increment,
name char(32),
balance int
); # 插入数据
insert into user(name,balance)
values
('wsb',1000),
('egon',1000),
('ysb',1000); #原子操作
start transaction; # 开启事务
update user set balance=900 where name='wsb'; #买支付100元
update user set balance=1010 where name='egon'; #中介拿走10元
update user set balance=1090 where name='ysb'; #卖家拿到90元
commit; #出现异常,回滚到初始状态
start transaction;
update user set balance=900 where name='wsb'; #买支付100元
update user set balance=1010 where name='egon'; #中介拿走10元
uppdate user set balance=1090 where name='ysb'; #卖家拿到90元,出现异常没有拿到
# rollback; # 上述 update 操作的数据只是保存在内存中,此时 rollback 能让数据回滚到最初的状态;commit之后 rollback 就没有作用了
commit; # 想让内存的数据保存到 数据库中,则需要 commit
mysql> select * from user; +----+------+---------+
| id | name | balance |
+----+------+---------+
| 1 | wsb | 1000 |
| 2 | egon | 1000 |
| 3 | ysb | 1000 |
+----+------+---------+
rows in set (0.00 sec)
使用:
#思路:
delimiter //
create procedure p4(
out status int
)
BEGIN
1. 声明如果出现异常则执行{
set status = 1;
rollback;
} 开始事务
-- 由秦兵账户减去100
-- 方少伟账户加90
-- 张根账户加10
commit;
结束 set status = 2; END //
delimiter ; #实现
delimiter //
create PROCEDURE p5(
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; # 开启事务
DELETE from tb1;
insert into blog(name,sub_time) values('yyy',now());
COMMIT; -- SUCCESS
set p_return_code = 0; #0代表执行成功 END //
delimiter ;
python的事务开启:
示例一:
# coding=utf-8
import pymysql #添加数据 conn = pymysql.connect(host='localhost', port=3306, user='root', passwd='', db='yyy') cursor = conn.cursor() try:
insertSQL0="INSERT INTO ACCOUNT2 (name,balance) VALUES ('bart',1000)"
insertSQL1="UPDATE account2 set balance=balance-30 WHERE name='alex'"
insertSQL2="UPDATE account2 set balance=balance+30 WHERE name='ego'" cursor.execute(insertSQL0)
conn.commit() cursor.execute(insertSQL1)
raise Exception #模拟出现错误
cursor.execute(insertSQL2)
cursor.close()
conn.commit() except Exception as e:
conn.rollback() #回滚
conn.commit() cursor.close()
conn.close()
示例二:
try:
cursor.execute(sql_1)
cursor.execute(sql_2)
cursor.execute(sql_3)
except Exception as e:
connect.rollback() # 事务回滚
print('事务处理失败', e)
else:
connect.commit() # 事务提交
print('事务处理成功', cursor.rowcount) # cursor.rowcount 是一个只读属性,返回执行execute()方法后影响的行数。
# 关闭连接
cursor.close()
connect.close()
MySQL:视图、触发器、存储过程、事务的更多相关文章
- mysql 视图 触发器 存储过程 函数事务 索引
mysql 视图 触发器 存储过程 函数事务 索引 视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,并可以将其当 ...
- Mysql 视图,触发器,存储过程,函数,事务
视图 视图虚拟表,是一个我们真实查询结果表,我们希望将某次查询出来的结果作为单独的一个表,就叫视图,无法对图字段内容进行增删改. --格式: CREATE VIEW 视图名字 AS 操作; --比如: ...
- Mysql 视图 游标 触发器 存储过程 事务
Mysql 视图 触发器 存储过程 游标 游标是从数据表中提取出来的数据,以临时表的形式存放在内存中,在游标中有一个数据指针,在初始状态下指向的是首记录,利用fetch语句可以移动该指针,从而对游标中 ...
- day40 mycql 视图,触发器,存储过程,函数
视图,触发器,存储过程,自定义函数 -- 回顾 1.mysql 约束 1.非空 not null 2. 主键约束 primary key 3. 唯一约束 unique 4. 外键约束 foreign ...
- MySQL 视图触发器事务存储过程函数
事务 致命三问 什么是事务:开启了一个包含多条SQL语句的事务,这些SQL语句要么都执行成功,要么有别想成功:例如A向B转账,二人账户并不属于一家银行,在转账过程中由于网络问题,导致A显示转账 成功 ...
- MySQL——视图/触发器/事务/存储过程/函数/流程控制
一 视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,可以将该结果集当做表来使用. 使用视图我们可以把查询过程中的 ...
- mysql视图、触发事务、存储过程
视图 视图是一个虚拟表(非真实存在的),其本质就是根据SQL语言获取动态的数据集,并为其命名,用户使用时只需要使用名称即可获得结果集,可以将结果集当做表来使用. 视图是存在数据库中的,如果我们程序中使 ...
- python mysql 视图 触发器 事物 存储过程 用户授权 数据备份还原
###################总结########### 视图是一个虚拟表(非真实存在) 是跑在内存中的表,真实表是在硬盘上的表 使用视图我们可以把查询过程中的临时表摘出来,保存下来,用视图去 ...
- mysql视图 触发器 事物 函数 存储过程
一 视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,可以将该结果集当做表来使用. 使用视图我们可以把查询过程中的 ...
- Mysql学习---视图/触发器/存储过程/函数/执行计划/sql优化 180101
视图 视图: 视图是一个虚拟表(非真实存在),动态获取数据,仅仅能做查询操作 本质:[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,并可以将其当作表来使用.由 ...
随机推荐
- VS2010的一个错误,无法加载类型
一个解决方案中的一个项目X,启动时总是报错,无法加载一个同一个解决方案中另一个项目A生成EXE中的数据类型. 做了如下的步骤解决问题. 1:检查项目A,未发现错误,调试启动A,一切正常. 2:检查项目 ...
- jmeter(四)检查点
JMeter也有像LR中的检查点,本篇就来介绍下JMeter的检查点如何去实现. JMeter里面的检查点通过添加断言来完成. 检查点:上一章讲到,我们对用户名和密码进行了参数化,那么怎样来判断jme ...
- jquery + ajax 实现多条件查询
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="JquerySort.aspx. ...
- poj3109 Inner Vertices
思路: 树状数组 + 扫描线. 实现: #include <cstdio> #include <vector> #include <algorithm> using ...
- 把json数据转化成对象
把json数据转化到一个对象中,再用对象直接调用 package com.lxj.register; import java.io.BufferedReader; import java.io.IOE ...
- 1、QQ装机部落---腾讯软件
亲,赚钱快人一步,我给你推荐QQ装机部落!大品牌,口碑好,知名软件,绿色无毒,每天结算,回报高!到这里注册:http://zjbl.qq.com/#/?invid=476058088 返利网邀请码立即 ...
- PHP网络协议相关考点
HTTP状态码 HTTP状态码(HTTP Status Code)是用以表示网页服务器HTTP响应状态的3位数字代码. HTTP状态码主要有5种,代表5种不同类型的响应: 1xx:信息性状态码,代表接 ...
- JS对json中某字段进行排序
var data =[ { "cid":1, "name":"aaa", "price":1000 },{ " ...
- 以JSONobject形式提交http请求
总结一下设置图标的三种方式: (1)button属性:主要用于图标大小要求不高,间隔要求也不高的场合. (2)background属性:主要用于能够以较大空间显示图标的场合. (3)drawableL ...
- cocos2dx游戏如何架构
声明:此篇文章不介绍如何使用cocos2dx制作游戏.站在架构师的角度如果制作游戏. 以我多年的游戏开发经验,和其他技术积累, 市面的所谈的一些软件架构模式都不太适合游戏软件. 我指的架构模式,MVC ...