【连表操作】

 1 建表
 2 create table dep1(
 3     id int,
 4     name varchar(20)
 5     );
 6 create table emp1(
 7     id int primary key auto_increment,
 8     name varchar(20),
 9     sex enum('male','female') not null default 'male',
10     age int,
11     dep_id int
12     );
13 
14 
15 插入数据
16     insert into dep1 values
17     (200,'技术'),
18     (201,'人力资源'),
19     (202,'销售'),
20     (203,'运营');
21 
22 insert into emp1(name,sex,age,dep_id) values
23 ('jason','male',18,200),
24 ('egon','female',48,201),
25 ('kevin','male',18,201),
26 ('nick','male',28,202),
27 ('owen','male',18,203),
28 ('jerry','female',18,204);
29 
30 select * from dep1;
31 select * from emp1;
32 
33 ----------------------------------------------操作
34 1.查询jason这个人的部门名称
35     拼表操作:
36     select * from dep1,emp1;     将两张表拼成一张表,结果叫:笛卡尔积
37     或是
38     select * from emp1,dep1 where emp1.dep_id=dep1.id;
39 
40 MySQL在后面查询数据的过程中,肯定会经常用到拼表操作
41 所以特地开始了对应的方法:
42 *********************************重要
43     inner join: 内连接
44     left join:  左连接
45     right join: 右连接
46     union:      全连接
47 
48 
49 使用场景
50 inner join:内连接             on依据
51     select * from emp1 inner join dep1 on dep1.id=emp1.dep_id;
52     但这时候发现,有数据丢失,原因是,内连接,只拼接两张表共有的数据部分
53 
54 left join:左连接
55     select * from emp1 left join dep1 on dep1.id=emp1.dep_id;
56     左边的表所有的数据都展示出来,没有对应的项就用null填充
57 
58 right join:右连接
59     select * from emp1 right join dep1 on dep1.id=emp1.dep_id;
60     右边的表所有的数据都展示出来,没有对应的项就用null填充,(但是我的显示数据丢失)
61 
62 union:       全连接,左右两个表所有的数据都展示出来
63     select * from emp1 left join dep1 on dep1.id=emp1.dep_id
64     union
65     select * from emp1 right join dep1 on dep1.id=emp1.dep_id;

【子查询】

子查询就是我们平时解决问题的思路
    分步骤解决问题
    第一步........
    第二步........
将一个查询语句的结果当作另外一个查询语句的条件取使用

1.查询部门是技术部门或者是人力字段的员工信息
    1).获取部门的id号
    2).再去员工表里面筛选出对应的员工
    select id from dep1 where name='技术' or name='人力资源';
    select name from emp1 where dep1_id in (200,201);

精简写法:
    select * from emp1 where dep_id in (select id from dep1 where  name='技术' or name='人力资源');

总结:
    表的查询结果可以作为其他表的查询条件,也可以通过起别名的方式把它当作一个虚拟表根其他表关联
    多表查询就两种方式:1.先拼接表再查询 2.子查询一步一步来


------------------------------------------------------
练习
查询平均年龄在25岁以上的部门名称
只要涉及到多表查询,就有两种思路:
方式一:连表操作
先拿到部门和员工表,拼接之后的结果
得出需要进行分组
select dep1.name from emp1 inner join dep1 on emp1.dep_id=dep1.id
group by dep1.name
having avg(age)>25;

2.子查询
select name from dep1 where id in (
select dep_id from emp1 group by dep_id
having avg(age)>25
);

3.关键字 exists
只返回T or N
返回T的时候外层查询语句执行
返回F的时候外层查询语句不执行
select * from emp1 where exists (
select * from dep1 where id>3);

select * from emp1 where exists (
select * from dep1 where id>300); (后面不执行)

【python操作数据库pymysql】

基本使用

安装
    pip3 install pymysql

创建文件名不要和模块名一样

import pymysql

# 连接数据库
conn = pymysql.connect(
    host='127.0.0.1',
    user='root',
    password='199721',
    charset='utf8',  # 不要加 -
    port=3306,
    database='day4')

cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)  # 产生一个游标对象,来帮我们执行命令的
# cursor=pymysql.cursor.DictCursor # 查询结果以字典的形式返回

sql = 'select * from teacher'
res = cursor.execute(sql)
# print(res)  # execute返回的是当前sql语句所影响的行数,该返回值我们一般不用
# 获取命令执行的查询结果
print(cursor.fetchone())  # 只拿一条,并打印第一个元素{'id': 100, 'cl_name': '高三1班 '}
print(cursor.fetchmany(2))  # 可以指定拿几条
print(cursor.fetchall())  # 读取所有的数据
cursor.scroll(1, 'relative')  # 相对于光标所在的位置继续往后移动1位
cursor.scroll(1, 'absolute')  # 相对于数据的开头位置继续往后移动1位
conn.close()  # 关闭连接

===================================

 1 pymysql操作数据库
 2 
 3 增删改查
 4 
 5 #  1. pymysql操作数据库的增删改查
 6 import pymysql
 7 
 8 conn = pymysql.connect(
 9     host='127.0.0.1',
10     user='root',
11     password='199721',
12     charset='utf8',
13     port=3306,
14     database='day4')
15 
16 cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)  # 产生一个游标对象,来帮我们执行命令的
17 
18 #
19 sql = 'insert into user(name,password) values(%s,%s)'
20 rows = cursor.execute(sql, ('jackson', 1234))  # 放的是元组
21 # rows=cursor.executemany(sql,[('jason',123456),('jason2',123456),('jason3',123456)])  # 列表套元组
22 print(rows)  # 到这里其实没有增加
23 conn.commit()  # 我们需要确认
24 
25 
26 # 修改
27 sql = 'update user set name="jasonNB" where id=1'
28 rows = cursor.execute(sql)
29 print(rows)  # 在表中还是没有修改
30 conn.commit()  # 确认
31 
32 #
33 sql = 'delete from user where id=1'
34 rows = cursor.execute(sql)
35 print(rows)  # 也没有用
36 conn.commit()  # 确认
37 
38 
39 #
40 sql = 'select * from user'
41 rows = cursor.execute(sql)
42 print(rows)  #
43 
44 # 增删改查中,查的结果是返回一个数字,表示影响的行数,其他操作返回的数字表示操作的行数
45 # 需要二次确认,才能增删改

------------------------------------------------------------------------------

(在pymysql模块中如何调用存储过程)

 1 import pymysql
 2 
 3 conn = pymysql.connect(
 4     host='127.0.0.1',
 5     user='root',
 6     password='199721',
 7     charset='utf8',
 8     port=3306,
 9     database='day4')
10 
11 cursor = conn.cursor(pymysql.cursors.DictCursor)
12 # # 调用存储过程
13 # cursor.callproc('proc_test', [1, 2])
14 # print(cursor.fetchall())
15 cursor.execute('select * from user')
16 print(cursor.fetchall())

 

【sql注入问题及解决办法】

SQL语言主要用于存取数据、查询数据、更新数据和管理关系数据库系统,SQL语言由IBM开发。

SQL语言分为3种类型:

  1、DDL语句 数据库定义语言: 数据库、表、视图、索引、存储过程,例如CREATE DROP ALTER

  2、DML语句 数据库操纵语言: 插入数据INSERT、删除数据DELETE、更新数据UPDATE、查询数据SELECT

  3、DCL语句 数据库控制语言: 例如控制用户的访问权限GRANT、REVOKE

sql注入: 利用现有的程序,将恶意的sql命令注入到后台的数据库引擎执行的能力 像符号--会注释掉之后的sql,根本 原理就是字符串的拼接name=‘%s' 原生sql中让execute帮做拼接就可以,django的orm种就不会存在这个问题

 1 import pymysql
 2 
 3 conn = pymysql.connect(
 4     host='127.0.0.1',
 5     user='root',
 6     password='199721',
 7     charset='utf8',
 8     port=3306,
 9     database='day4')
10 
11 cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)  # 产生一个游标对象,来帮我们执行命令的
12 username = input('请输入用户名:')
13 password = input('请输入密码:')
14 sql = "select* from user where name='%s' and password='%s'"%(username,password)
15 rows = cursor.execute(sql)
16 if rows:
17     print('登录成功')
18     print(cursor.fetchall())
19 else:
20     print('用户名或密码错误')
21 
22 ---------------------------------------------
23 上述输入密码账号看似没有问题,但是当我们不输入密码的时候,提示我们也能登录成功,其实这就是sql注入问题
24 解决办法
25 
26 sql = "select * from user where name=%s and password=%s"
27 # 不要手动拼接数据,先用%s占位,然后将需要拼接的数据直接交给execute方法即可
28 rows = cursor.execute(sql, (username, password))
29 # 自动识别sql里面的%s,然后将数据替换进去
30 if rows:
31     print('登录成功')
32 else:
33     print('用户名或密码错误')
34 
35 ----------------------------------------------
36 PS:2024.5.19我重新测试了sql注入问题,发现这个漏洞已经解决了,不知道是我测试方法不对还是什么

【connect中一些参数的意思】

 1 conn = pymysql.connect(
 2     host='127.0.0.1',
 3     user='root',   %
 4     password='199721',
 5     charset='utf8',
 6     port=3306,
 7     database='day4')
 8 
 9 host:代表地址,
10 user:登录mysql 的用户名,
11 password:登录mysql 的密码,
12 charser:代表编码格式,
13 port:端口号,常规的很多都是3306也有自定义,
14 database:数据库名称

 

posted on 2024-05-19 18:53  认真的六六  阅读(8)  评论(0编辑  收藏  举报