[MySQL数据库之Navicat.pymysql模块、视图、触发器、存储过程、函数、流程控制]

Navicat

Navicat是一套快速、可靠并价格相当便宜的数据库管理工具,专为简化数据库的管理及降低系统管理成本而设。它的设计符合数据库管理员、开发人员及中小企业的需要。Navicat 是以直觉化的图形用户界面而建的,让你可以以安全并且简单的方式创建、组织、访问并共用信息。

我们在终端操作MySQL没有自动提示,也无法自动保存等等不方便开发,Navicat内部封装了所有的操作数据库命令,用户在使用它的时候只需要鼠标点点点即可完成操作,无需书写sql语句。

pymysql模块

下载安装pymysql模块

pip3 install pymysql
往ttt表插入数据

连接、执行sql、关闭(游标)

# pip3 install pymysql

# 导入模块
import pymysql # 连接
conn = pymysql.connect(host="127.0.0.1",port=3306,database='db3',user="root",password="111") # 创建游标(指定参数)
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) # 执行sql语句,返回sql查询成功的记录行数,并打印
rows = cursor.execute("select * from ttt;")
print(rows) # 拿到sql语句查询的数据结果并打印
res = cursor.fetchall()
print(res) # 关闭游标
cursor.close() # 关闭连接
conn.close() '''
注意:默认情况下,我们获取到的返回值是元组,只能看到每行的数据,却不知道每一列代表的是什么,
这个时候可以使用以下方式来返回字典,每一行的数据都会生成一个字典:
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
在实例化的时候,将属性cursor设置为pymysql.cursors.DictCursor ps:查询是有结果返回的,执行增、删、改就不需要用到fetchall了
'''

execute()之slq注入:连接,用户登录认证

创建user表
# 导入模块
import pymysql
# 连接
conn = pymysql.connect(host="127.0.0.1",port=3306,database='db3',user="root",password="111")
# 创建游标(指定参数)
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) # 用户输入用户名,密码
user = input('请输入用户名:').strip()
pwd = input('请输入密码:').strip() # execute帮我们做字符串拼接,我们无需且一定不能为%s加引号
rows = cursor.execute('select * from user where username = %s and password = %s',args=(user,pwd))
# 判断
if rows:
print('登录成功!')
else:
print('用户名或密码错误!') # 关闭游标连接
cursor.close()
conn.close()

增、改、删 conn.commit()

  在数据库里增 删 改 的时候 必须要进行提交,否则插入的数据不生效。

# 导入模块
import pymysql
# 连接
conn = pymysql.connect(host="127.0.0.1",port=3306,database='db3',user="root",password="111")
# 游标
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) # 以下操作演示还是参照db3库下的user表
# 操作:增(插入数据也可同时插入多条)
cursor.execute("insert into user values(5,'haha','123'),(6,'hanzi','222');") # 操作:改(将id为3的名字改为lili)
cursor.execute("update user set username = 'lili' where id = 3;") # 操作:删(删除id为2的一行记录)
rows = cursor.execute("delete from user where id = 2;")
print(rows) # 操作任意增删改操作一定记得commit
conn.commit() # 关闭游标和连接
cursor.close()
conn.close()

查:fetchone、fetchmany、fetchall

fetchone():获取下一行的数据,第一次为首行。

fetchall():获取所有行数数据。

fetchmany(2):获取2行数据.

# 导入模块
import pymysql
# 连接
conn = pymysql.connect(host="127.0.0.1",port=3306,database='db3',user="root",password="111")
# 游标
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) # 执行sql语句查询整张表的数据(打印只显示行数)
rows = cursor.execute("select * from user;")
print(rows) # fetchall():获取所有行数数据。
res = cursor.fetchall()
print(res) # fetchone():获取下一行的数据,第一次为首行
print(cursor.fetchone()) # 查询第一行
print(cursor.fetchone()) # 查询第二行
print(cursor.fetchone()) # 查询第三行 # fetchmany(2):获取3行数据.用列表套字典显示
print(cursor.fetchmany(2)) # 打印结果
'''
{'id': 1, 'username': 'geng', 'password': '234'}
{'id': 3, 'username': 'lili', 'password': '111'}
{'id': 4, 'username': 'liu', 'password': '222'}
[{'id': 5, 'username': 'haha', 'password': '123'},
{'id': 6, 'username': 'hanzi', 'password': '222'}]
''' # 控制游标移动
# cursor.scroll(3,mode='absolute') # 绝对位置移动
# cursor.scroll(3,mode='relative') # 相对当前位置移动
print(cursor.fetchone())
print(cursor.fetchone())
print(cursor.fetchone())
cursor.scroll(2,mode='relative')
cursor.scroll(2,mode='absolute') # 永远参照开头移动
print(cursor.fetchone()) cursor.close()
conn.close()

lastrowid()获取插入的最后一条数据的自增ID

# 导入模块
import pymysql
# 连接
conn = pymysql.connect(host="127.0.0.1",port=3306,database='db3',user="root",password="111")
# 游标
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) # 插入sql语句
sql='insert into user(username,password) values("xxx","123");'
rows=cursor.execute(sql)
print(cursor.lastrowid) # 在插入语句后查看 # 一定要commit
conn.commit() # 关闭游标和连接
cursor.close()
conn.close()

视图

概念:通过查询得到的一张虚拟表,然后保存下来就是视图

视图的好处:如果要频繁使用某张虚拟表,那么就可以保存为视图,以后查找就直接拿这个视图就会非常方便

视图语法规则:

# 新增视图
create view emp_dep_view as
select employee.*,department.name as depname from employee inner join department
on employee.dep_id = department.id; # 修改视图
alter view emp_dep_view as
select employee.*,department.name as depname from employee inner join department
on employee.dep_id = department.id; # 删除视图
drop view emp_dep_view;

视图需要注意的点:

1、视图在硬盘中只有表结构文件,没有表数据文件,数据取自原查询的表

2、视图常用于查询,尽量不要修改视图表中的数据,修改数据可能会导致原表数据出现问题

触发器

概念:在对某张表进行增删改的操作时会自动触发另外一部分功能的执行的行为被称为触发器

为什么用触发器:触发器专门针对我们对某张表的增删改的行为,实际需求中我们可能需要监控这张表的操作并执行一些其他功能,这时候使用触发器将会非常方便。

创建触发器语法规则:

# 针对插入
create trigger tri_after_insert_t1 after insert on 表名 for each row
begin
sql代码。。。
end
create trigger tri_after_insert_t2 before insert on 表名 for each row
begin
sql代码。。。
end # 针对删除
create trigger tri_after_delete_t1 after delete on 表名 for each row
begin
sql代码。。。
end
create trigger tri_after_delete_t2 before delete on 表名 for each row
begin
sql代码。。。
end # 针对修改
create trigger tri_after_update_t1 after update on 表名 for each row
begin
sql代码。。。
end
create trigger tri_after_update_t2 before update on 表名 for each row
begin
sql代码。。。
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 // # 将mysql默认的结束符由;换成//
create trigger tri_after_insert_cmd after insert on cmd for each row
begin
if NEW.success = 'no' then # 新记录都会被MySQL封装成NEW对象
insert into errlog(err_cmd,err_time) values(NEW.cmd,NEW.sub_time);
end if;
end //
delimiter ; # 结束之后记得再改回来,不然后面结束符就都是$$了 #往表cmd中插入记录,触发触发器,根据IF的条件决定是否插入错误日志
INSERT INTO cmd (
USER,
priv,
cmd,
sub_time,
success
)
VALUES
('egon','0755','ls -l /etc',NOW(),'yes'),
('egon','0755','cat /etc/passwd',NOW(),'no'),
('egon','0755','useradd xxx',NOW(),'no'),
('egon','0755','ps aux',NOW(),'yes'); # 查询errlog表记录
select * from errlog; # 删除触发器
drop trigger tri_after_insert_cmd;

存储过程

概念:存储过程包含一堆sql语句,可以通过对存储过程的名字来调用执行内部语句,类似于其他编程语言中的函数

存储过程的三种开发模型:

第一种:

应用程序:只需要开发应用程序的逻辑

mysql:事先编写好存储过程,供应用程序随时调用

优点:开发效率和执行效率高

缺点:人为因素较多,跨部门沟通等,扩展性较差

第二种:

应用程序:除了要开发应用程序逻辑,还需要编写原生的sql语句

优点:扩展性较高,都根据mysql语法规则来编写sql语句即可

缺点:编写原生sql语句十分复杂,并且要考虑到sql语句优化的问题,这就导致了开发效率和执行效率降低的问题 

第三种:

应用程序:只考虑应用程序的逻辑,不需要管SQL语句的实现,基于第三方的工具和库

优点:开发效率高,直接调用已封装好的功能和方法就好,有更好的兼容性

缺点:执行效率比较低,执行效率不如第二种

如何创建存储过程:

# 存储过程在那个库下创建即在哪个库下面生效,不是全局的

# 1、直接在mysql中调用
set @res=10 # res的值是用来判断存储过程是否被执行成功的依据,所以需要先定义一个变量@res存储10
call p1(2,4,10); # 报错
call p1(2,4,@res); # 查看结果
select @res; # 执行成功,@res变量值发生了变化 # 2、在python程序中调用
pymysql链接mysql
产生的游表cursor.callproc('p1',(2,4,10)) # 内部原理:@_p1_0=2,@_p1_1=4,@_p1_2=10;
cursor.excute('select @_p1_2;') # 3、存储过程与事务使用举例(了解)
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;
    update user set balance=900 where id =1;
    pdate user123 set balance=1010 where id = 2;
    pdate user set balance=1090 where id =3;
  COMMIT;   -- SUCCESS
  set p_return_code = 0; #0代表执行成功 END //
delimiter ;

函数

注意与存储过程的区别,mysql内置的函数只能在sql语句中使用!

参考博客:http://www.cnblogs.com/linhaifeng/articles/7495918.html#_label2

需要掌握函数:date_format

# 1 基本使用
mysql> SELECT DATE_FORMAT('2009-10-04 22:23:00', '%W %M %Y');
-> 'Sunday October 2009'
mysql> SELECT DATE_FORMAT('2007-10-04 22:23:00', '%H:%i:%s');
-> '22:23:00'
mysql> SELECT DATE_FORMAT('1900-10-04 22:23:00',
-> '%D %y %a %d %m %b %j');
-> '4th 00 Thu 04 10 Oct 277'
mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00',
-> '%H %k %I %r %T %S %w');
-> '22 22 10 10:23:00 PM 22:23:00 00 6'
mysql> SELECT DATE_FORMAT('1999-01-01', '%X %V');
-> '1998 52'
mysql> SELECT DATE_FORMAT('2006-06-00', '%d');
-> '00' # 2 准备表和记录
CREATE TABLE blog (
id INT PRIMARY KEY auto_increment,
NAME CHAR (32),
sub_time datetime
); INSERT INTO blog (NAME, sub_time)
VALUES
('第1篇','2015-03-01 11:31:21'),
('第2篇','2015-03-11 16:31:21'),
('第3篇','2016-07-01 10:21:31'),
('第4篇','2016-07-22 09:23:21'),
('第5篇','2016-07-23 10:11:11'),
('第6篇','2016-07-25 11:21:31'),
('第7篇','2017-03-01 15:33:21'),
('第8篇','2017-03-01 17:32:21'),
('第9篇','2017-03-01 18:31:21'); # 3. 提取sub_time字段的值,按照格式后的结果即"年月"来分组
SELECT DATE_FORMAT(sub_time,'%Y-%m'),COUNT(1) FROM blog GROUP BY DATE_FORMAT(sub_time,'%Y-%m'); # 结果
+-------------------------------+----------+
| DATE_FORMAT(sub_time,'%Y-%m') | COUNT(1) |
+-------------------------------+----------+
| 2015-03 | 2 |
| 2016-07 | 4 |
| 2017-03 | 3 |
+-------------------------------+----------+
3 rows in set (0.00 sec)

流程控制

# if条件语句
delimiter //
CREATE PROCEDURE proc_if ()
BEGIN declare i int default 0;
if i = 1 THEN
SELECT 1;
ELSEIF i = 2 THEN
SELECT 2;
ELSE
SELECT 7;
END IF; END //
delimiter ; # while循环
delimiter //
CREATE PROCEDURE proc_while ()
BEGIN DECLARE num INT ;
SET num = 0 ;
WHILE num < 10 DO
SELECT
num ;
SET num = num + 1 ;
END WHILE ; END //
delimiter ;

[MySQL数据库之Navicat.pymysql模块、视图、触发器、存储过程、函数、流程控制]的更多相关文章

  1. mysql 视图 触发器 存储过程 函数事务 索引

    mysql 视图 触发器 存储过程 函数事务 索引 视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,并可以将其当 ...

  2. day40 mycql 视图,触发器,存储过程,函数

    视图,触发器,存储过程,自定义函数 -- 回顾 1.mysql 约束 1.非空 not null 2. 主键约束 primary key 3. 唯一约束 unique 4. 外键约束 foreign ...

  3. MySQL数据库篇之pymysql模块的使用

    主要内容: 一.pymysql模块的使用 二.pymysq模块增删改查 1️⃣  pymsql模块的使用 1.前言:之前我们都是通过MySQL自带的命令行客户端工具mysql来操作数据库, 那如何在p ...

  4. MySQL——视图/触发器/事务/存储过程/函数/流程控制

    一 视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,可以将该结果集当做表来使用. 使用视图我们可以把查询过程中的 ...

  5. Mysql学习---视图/触发器/存储过程/函数/执行计划/sql优化 180101

    视图 视图: 视图是一个虚拟表(非真实存在),动态获取数据,仅仅能做查询操作 本质:[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,并可以将其当作表来使用.由 ...

  6. MySQL 视图 触发器 事务 存储过程 函数 流程控制 索引与慢查询优化

    视图 1.什么是视图? 视图就是通过查询得到的一张虚拟表,然后保存下来,下次可直接使用 2.为什么要使用视图? 如果要频繁使用一张虚拟表,可以不用重复查询 3.如何使用视图? create view ...

  7. Mysql 视图,触发器,存储过程,函数,事务

    视图 视图虚拟表,是一个我们真实查询结果表,我们希望将某次查询出来的结果作为单独的一个表,就叫视图,无法对图字段内容进行增删改. --格式: CREATE VIEW 视图名字 AS 操作; --比如: ...

  8. mysql 视图 触发器 事物 存储过程 函数 流程控制

    1.视图 *** 视图是有一条sql语句的查询结果构成的虚拟表 其不是物理存在的 使用方式与普通表相同 视图的作用1.简化sql语句的编写 2.限制可以查看的数据 可以使用权限来完成 权限某一个库 的 ...

  9. MySQL 索引 视图 触发器 存储过程 函数

    1.索引 索引相当于图书的目录,可以帮助用户快速的找到需要的内容. 数据库利用各种各样的快速定位技术,能够大大提高查询效率.特别是当数据量非常大,查询涉及多个表时,使用索引往往能使查询速度加快成千上万 ...

随机推荐

  1. (三)SpringBoot启动过程的分析-创建应用程序上下文

    -- 以下内容均基于2.1.8.RELEASE版本 紧接着上一篇(二)SpringBoot启动过程的分析-环境信息准备,本文将分析环境准备完毕之后的下一步操作:ApplicationContext的创 ...

  2. vue实现拖拽排序

    基于vue实现列表拖拽排序的效果 在日常开发中,特别是管理端,经常会遇到要实现拖拽排序的效果:这里提供一种简单的实现方案. 此例子基于vuecli3 首先,我们先了解一下js原生拖动事件: 在拖动目标 ...

  3. Asp.Net Core 5 REST API - Step by Step

    翻译自 Mohamad Lawand 2021年1月19日的文章 <Asp.Net Core 5 Rest API Step by Step> [1] 在本文中,我们将创建一个简单的 As ...

  4. [模拟]P1046 陶陶摘苹果

    陶陶摘苹果 ## 题目描述 陶陶家的院子里有一棵苹果树,每到秋天树上就会结出10个苹果.苹果成熟的时候,陶陶就会跑去摘苹果.陶陶有个30厘米高的板凳,当她不能直接用手摘到苹果的时候,就会踩到板凳上再试 ...

  5. Python中切片的应用

    Python中切片的应用 Python中可以通过切片实现对列表或者字符串取指定范围的操作,实际就是通过对列表或者字符串通过索引进行操作. 具体细节点击廖雪峰Python教程,其中的课后小问题在此记录下 ...

  6. navcat卸载

    https://www.cnblogs.com/mysterious-killer/p/10416739.html

  7. (十五)struts2的文件上传和下载

    文件上传的原理 我们以前学习上传的时候知道需要将表单的enctype属性设置为multipart/form-data. 表单的enctype属性指定的是表单数据的编码方式,有三个值: -applica ...

  8. 记一次metasploitable2内网渗透之samba服务的攻击

    80端口中对应一些web靶场,在这里不记录 111端口的利用是向rpcbind服务的UDP套接字发送60字节载荷,便可填充目标内存,搞崩主机系统.在这里也不记录 Samba服务简介 Samba是在Li ...

  9. leetcode 刷题(数组篇)26题 删除有序数组中的重复值 (双指针)

    题目描述 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度. 不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额 ...

  10. isAssignableFrom与instanceof

    isAssignableFrom()方法与instanceof关键字的区别总结为以下两个点: isAssignableFrom()方法是从类继承的角度去判断,instanceof关键字是从实例继承的角 ...