视图 触发器 函数 流程控制 存储过程 SQL注入问题

Posted 我的紫霞辣辣

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了视图 触发器 函数 流程控制 存储过程 SQL注入问题相关的知识,希望对你有一定的参考价值。

视图

视图就是通过查询得到一张虚拟表(非真实存在),然后保存下来,下次可以直接使用,用户使用时直接使用【视图表名】即可获取结果集。
视图有明显地效率问题,并且视图是存放在数据库中的,如果我们程序中使用的sql过分依赖数据库中的视图,即强耦合,那就意味着扩展sql极为不便,因此并不推荐使用。

使用视图的注意点:

  1.创建视图在硬盘上只会有表结构,没有表数据,数据并没有存在硬盘(数据还是来自之前的表)

  2.视图一般只用来查询,里面的数据不要进行修改,可能会影响真正的表

创建视图语法

  create view 表名 as 虚拟表的查询语句
# 创建一张数据表
select * from employee;
+----+--------+--------+-----+------------+--------------+--------------+----------+--------+-----------+
| id | name   | sex    | age | hire_date  | post         | post_comment | salary   | office | depart_id |
+----+--------+--------+-----+------------+--------------+--------------+----------+--------+-----------+
|  1 | sun    | male   |  18 | 2017-03-01 | 猥琐欲为     | NULL         |  1000.22 |    401 |         1 |
|  2 | haha   | male   |  78 | 2015-03-02 | teacher      | NULL         | 10000.31 |    401 |         1 |
|  3 | xixi   | male   |  81 | 2013-03-05 | teacher      | NULL         |  8300.31 |    401 |         1 |
|  4 | dudu   | male   |  72 | 2015-03-12 | teacher      | NULL         |  3100.00 |    401 |         1 |
|  5 | biubiu | male   |  28 | 2014-03-18 | teacher      | NULL         |  5000.00 |    401 |         1 |
|  6 | lala   | female |  58 | 2021-03-23 | teacher      | NULL         |  1020.00 |    401 |         1 |
|  7 | bubu   | male   |  38 | 2015-05-20 | teacher      | NULL         |  1501.00 |    401 |         1 |
|  8 | bobo   | male   |  55 | 2011-03-10 | teacher      | NULL         |  8222.00 |    401 |         1 |
|  9 | 哈哈   | male   |  48 | 2012-03-21 | sale         | NULL         |  3333.00 |    402 |         2 |
| 10 | 呵呵   | male   |  55 | 2013-06-20 | sale         | NULL         |  1050.00 |    402 |         2 |
| 11 | 西西   | male   |  38 | 2014-07-20 | sale         | NULL         |  1200.31 |    402 |         2 |
| 12 | 嘟嘟   | male   |  18 | 2018-12-01 | sale         | NULL         | 10011.00 |    402 |         2 |
| 13 | 萌萌   | male   |  38 | 2010-05-02 | sale         | NULL         | 10020.00 |    402 |         2 |
| 14 | 拉拉   | male   |  58 | 2005-03-25 | sale         | NULL         |  6250.00 |    402 |         2 |
| 15 | 娜娜   | male   |  18 | 2010-03-19 | operation    | NULL         | 20000.00 |    403 |         3 |
| 16 | 宝宝   | female |  18 | 2015-04-05 | operation    | NULL         | 20000.00 |    403 |         3 |
| 17 | 辣辣   | male   |  18 | 2009-03-15 | operation    | NULL         | 18220.00 |    403 |         3 |
| 18 | 蟹蟹   | male   |  18 | 2008-03-20 | operation    | NULL         | 50000.00 |    403 |         3 |
+----+--------+--------+-----+------------+--------------+--------------+----------+--------+-----------+

# 查看salary大于10000的虚拟表
select name,age,post from employee where salary > 10000;
+--------+-----+-----------+
| name   | age | post      |
+--------+-----+-----------+
| haha   |  78 | teacher   |
| 嘟嘟   |  18 | sale      |
| 萌萌   |  38 | sale      |
| 娜娜   |  18 | operation |
| 宝宝   |  18 | operation |
| 辣辣   |  18 | operation |
| 蟹蟹   |  18 | operation |
+--------+-----+-----------+

# 创建视图,将虚拟表的结果产生的表结构保存了,并没有表数据
# 每次我们使用视图的表数据,都是直接触发as后面的sql语句运行,通过查询得到的表数据
create view new_employee as select name,age,post from employee where salary > 10000;

# 查看视图数据
select * from new_employee;
+--------+-----+-----------+
| name   | age | post      |
+--------+-----+-----------+
| haha   |  78 | teacher   |
| 嘟嘟   |  18 | sale      |
| 萌萌   |  38 | sale      |
| 娜娜   |  18 | operation |
| 宝宝   |  18 | operation |
| 辣辣   |  18 | operation |
| 蟹蟹   |  18 | operation |
+--------+-----+-----------+

# 查看数据库指定目录下的视图数据,只有表结构
ls /service/mysql/data/db01
# new_employee.frm

# 修改视图表(本质就是修改视图as后面的sql语句规则)
alter view new_employee as select name,age from employee where id < 3;

select * from new_employee;
+------+-----+
| name | age |
+------+-----+
| sun  |  18 |
| haha |  78 |
+------+-----+

# 删除视图
drop view new_employee;

触发器

使用触发器可以定制用户对表进行【增、删、改】操作时前后的行为,注意:没有查询!!!

使用触发器可以帮助我们实现监控,日志,自动处理异常等等...

触发器可以在6种情况下自动触发 增前增后 删前删后 改前改后

创建触发器基本语法结构

  create trigger 触发器的名字 before/after insert/update/delete 表名
  for each row
  begin 
  	sql语句
  end

触发器无法由用户直接调用,而知由于对表的【增/删/改】操作被动引发的!!!

当cmd表中的记录success字段是no那么就触发触发器去执行errlog表中插入的数据

# 创建表字段
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")   	 # no代表执行失败
);

create table errlog(
id int primary key auto_increment,
err_cmd char(64),
err_time datetime
);

# 创建触发器
delimiter $$				# delimiter 声明sql语句的结束符号
# create trigger 触发器名 after insert 表名,插入表数据后被动引发触发器执行
create trigger tri_after_insert_cmd after insert on cmd 
for each row		
begin
    if new.success = "no" then      # new 指代的就是cmd表中的一条条数据对象(new.success ==> cmd.success)
    insert into errlog(err_cmd,err_time) values(new.cmd,new.sub_time);		# 必须加分号
    end if;			# 必须加分号
end $$
delimiter ;			# 重新声明sql语句符号为;

# 往表cmd中插入记录,触发触发器,根据if的条件决定是否插入错误日志
insert into cmd(user,priv,cmd,sub_time,success)
values("nana","0755","is -1 /etc",now(),"yes"),
      ("nana","0755","cat /etc/password",now(),"no"),
      ("nana","0755","useradd xxx",now(),"no");

select * from cmd;
+----+------+------+-------------------+---------------------+---------+
| id | user | priv | cmd               | sub_time            | success |
+----+------+------+-------------------+---------------------+---------+
|  1 | nana | 0755 | is -l /etc        | 2021-07-05 22:18:01 | yes     |
|  2 | nana | 0755 | cat /ect/password | 2021-07-05 22:18:01 | no      |
|  3 | nana | 0755 | useradd xxx       | 2021-07-05 22:18:01 | no      |
+----+------+------+-------------------+---------------------+---------+

# 查询错误日志,发现有两条数据
select * from errlog;
+----+-------------------+---------------------+
| id | err_cmd           | err_time            |
+----+-------------------+---------------------+
|  1 | cat /ect/password | 2021-07-05 22:18:01 |
|  2 | useradd xxx       | 2021-07-05 22:18:01 |
+----+-------------------+---------------------+

# 删除触发器
drop trigger tri_after_insert_cmd;  

函数

函数只能在sql语句中使用,不能独立调用!!!
若要想在begin…end…中写sql,请用存储过程!!!

内置函数

- 常见的内置函数
# 查看当前登陆的用户
select user();
+----------------+
| user()         |
+----------------+
| root@localhost |
+----------------+

# 查看当前时间
select now();
+---------------------+
| now()               |
+---------------------+
| 2021-07-05 22:45:03 |
+---------------------+

# 随机生成一个小数
select rand();
+--------------------+
| rand()             |
+--------------------+
| 0.6458554832691843 |
+--------------------+

# 四舍五入取值,保留两位小数
select round(6.666,2);
+----------------+
| round(6.666,2) |
+----------------+
|           6.67 |
+----------------+
- date_format内置函数,日期格式的拼接
# 创建表格
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');

# 查看表的数据
select * from blog;                                                                  
+----+------+---------------------+
| id | name | sub_time            |
+----+------+---------------------+
|  1 | 1    | 2015-03-01 11:31:21 |
|  2 | 2    | 2015-03-11 16:31:21 |
|  3 | 3    | 2016-07-01 10:21:31 |
|  4 | 4    | 2016-07-22 09:23:21 |
|  5 | 5    | 2016-07-23 10:11:11 |
|  6 | 6    | 2016-07-25 11:21:31 |
|  7 | 7    | 2017-03-01 15:33:21 |
|  8 | 8    | 2017-03-01 17:32:21 |
|  9 | 9    | 2017-03-01 18:31:21 |
+----+------+---------------------+

# 提取sub_time的字段数据,格式按照"年月"来进行分组
select date_format(sub_time,"%Y-%m") "时间(年-月)",count(id) from blog group by date_format(sformat(sub_time,"%Y-%m");
+-----------------+-----------+
| 时间(-)     | count(id) |
+-----------------+-----------+
| 2015-03         |         2 |
| 2016-07         |         4 |
| 2017-03         |         3 |
+-----------------+-----------+

自定义函数

函数中不要写sql语句(否则会报错),函数仅仅只是一个功能,是一个在sql中被应用的功能

# delimiter 声明sql语句的结束符号
delimiter $$		

# 定义一个函数f1
create function f1(
	a int,
	b int)
	returns int
	begin
	declare num int;
	set num = a+b;
	return(num);
	end$$
	
delimiter ; 

# 调用函数
select f1(2,3);
+---------+
| f1(2,3) |
+---------+
|       5 |
+---------+

# 创建一个表
create table t1(id int);

# 调用函数在表中插入数据
mysql> insert t1 values(f1(2,3));

# 查看表数据
select * from t1;
+------+
| id   |
+------+
|    5 |
+------+

# 删除自定义函数
drop function f1;

流程控制

if判断

# 定义一个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 ;

# 调用存储过程
call proc_if();
+---+
| 7 |
+---+
| 7 |
+---+

# 删除存储过程
drop procedure proc_if;

while循环

# 定义一个while循环的存储过程
delimiter //
create procedure proc_while ()
begin
    declare num int ;
    set num = 0 ;
   

以上是关于视图 触发器 函数 流程控制 存储过程 SQL注入问题的主要内容,如果未能解决你的问题,请参考以下文章

Learning-MySQL:视图触发器存储过程函数流程控制

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

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

mysql之视图触发器流程控制函数存储过程

视图 触发器 事务 存储过程 函数 流程控制

MySQL--视图触发器事务存储过程内置函数流程控制索引