当前位置: 首页 > news >正文

mysql数据库(六)pymysql、视图、触发器、存储过程、函数、流程控制、数据库连接池

pymysql、视图、触发器、存储过程、函数、流程控制、数据库连接池

文章目录

  • pymysql、视图、触发器、存储过程、函数、流程控制、数据库连接池
  • 一、pymysql
  • 二、视图
  • 三、触发器
  • 四、存储过程
  • 五、函数
  • 六、流程控制
  • 七、数据库连接池

一、pymysql

可以使用pip install pymysql安装pymysql模块。

import pymysql#连接数据库,host为ip,port为端口,database为库名,user为用户名,password为密码
conn =pymysql.connect(host="127.0.0.1",port=3306,database='t',user="root",password="123")
#创建游标对象,cursor=pymysql.cursors.DictCursor会返回字段:数据的字典,默认则是以元组的方式显示
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)#执行sql语句,返回结果为查询到记录的条数
res=cursor.execute("select * from t;")
#返回sql语句的查询结果
r=cursor.fetchall()
cursor.close()
conn.close()

上方代码中直接传入sql语句的方式可能存在一定的安全隐患,例如:

#绕过密码查询
#sql中--后面的会被注释掉
import pymysql
conn =pymysql.connect(host="127.0.0.1",port=3306,database='t',user="root",password="123")
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
sql="select * from t1 where user=%s and password=%s;"%('"bb123"--','')
res=cursor.execute(sql)
r=cursor.fetchall()
print(r)
cursor.close()
conn.close()<<<[{'id': 2, 'user': 'bb123', 'password': '123'}]

上述代码中传入的用户名后方添加了–也就相当于将查询语句中and password=%s的代码全部注释了,从而会出现绕过密码查询到用户的情况。

#不输入用户名登录
import pymysql
conn =pymysql.connect(host="127.0.0.1",port=3306,database='t',user="root",password="123")
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
sql="select * from t1 where user=%s and password=%s;"%('"" or 1=1--','')
res=cursor.execute(sql)
r=cursor.fetchall()
print(r)
cursor.close()
conn.close()
<<<[{'id': 1, 'user': 'cc123', 'password': '123'}, {'id': 2, 'user': 'bb123', 'password': '123'}]

我们知道mysql查询语句是通过逻辑判断的方式进行查询的,而1=1的结果永远为真,这就会导致没有输入任何用户和密码的情况下依然可以查询到用户信息。
为了避免上述的结果,我们可以让pymysql拼接字符串:

import pymysql
conn =pymysql.connect(host="127.0.0.1",port=3306,database='t',user="root",password="123")
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
#%s处千万不能加""
sql="select * from t1 where user=%s and password=%s;"
res=cursor.execute(sql,args=('"" or 1=1--',''))
r=cursor.fetchall()
print(r)
cursor.close()
conn.close()
<<<()

pymysql的增改删操作如下:

import pymysqlconn =pymysql.connect(host="127.0.0.1",port=3306,database='t',user="root",password="123")
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)sql='insert into t1 values(%s,%s,%s);'
#executemany可以一次操作多条记录
res=cursor.executemany(sql,[(3,'ee123','123'),(4,'ff123','123'),(5,'gg123','123')])
#res返回待插入的行数
print(res)#执行下面的语句后pymysql才会真正完成对数据库的增改删操作
conn.commit()
cursor.close()
conn.close()
import pymysqlconn = conn =pymysql.connect(host="127.0.0.1",port=3306,database='t',user="root",password="123")
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)sql='select * from t1'
res=cursor.execute(sql)
#fetchone表示一次取出一条记录
print(cursor.fetchone())
#fetchmany表示一次取出多条记录
print(cursor.fetchmany(2))
#scroll可以控制取记录的指针移动
#正右移负左移,relative表示当前位置,absolute表示起始位置
cursor.scroll(-2,'relative')
print(cursor.fetchmany(2))
cursor.scroll(2,'absolute')
print(cursor.fetchall())
cursor.close()
conn.close()<<<{'id': 1, 'user': 'cc123', 'password': '123'}
<<<[{'id': 2, 'user': 'bb123', 'password': '123'}, {'id': 3, 'user': 'ee123', 'password': '123'}]
<<<[{'id': 2, 'user': 'bb123', 'password': '123'}, {'id': 3, 'user': 'ee123', 'password': '123'}]
<<<[{'id': 3, 'user': 'ee123', 'password': '123'}, {'id': 4, 'user': 'ff123', 'password': '123'}, {'id': 5, 'user': 'gg123', 'password': '123'}]

上方的代码中第一次fetchone取出了查询到数据的第一条,指针向右移动一位,fetchmany(2)取出了第二第三条记录,指针再次向右移动两位,scroll(-2,‘relative’)以当前位置为基准让指针向左移动两位移回第二条记录的位置,因此后面的fetchmany(2)再次取出第二第三条记录,scroll(2,‘absolute’)以起始位置为基准,控制指针右移两位至第三条记录位置,最后的fetchall()则将第三条至最后一条记录之间的全部记录取出。

二、视图

视图是一个虚拟表,其本质是根据SQL语句获取动态的数据集,用户使用时只需使用名称即可获取结果集,可以将该结果集当做表来使用。
使用视图我们可以把查询过程中的临时表摘出来,用视图去实现,这样以后再想操作该临时表的数据时就无需重写复杂的sql了,直接去视图中查找即可,但视图有明显地效率问题,并且视图是存放在数据库中的,如果我们程序中使用的sql过分依赖数据库中的视图,这会使得扩展sql极为不便,因此视图不常使用。

#创建视图
create view teacher_view as select id,course,num from teacher where name='李平';
#从视图查询数据
select name from course where teacher_id = (select id from teacher_view);
#从视图中查询数据的效率非常低,甚至还不如写子查询语句查询的效率。#修改视图记录
update teacher_view set num='xxx';#插入记录
insert teacher_view values(5,'aaa','1234567');
#需要注意的是视图中的记录被修改时,原始表中的记录也会被修改,并且当创建视图涉及多个表时,视图的记录可能根本无法修改。因此我们不应该修改视图中存放的记录。#修改视图存放的内容
alter view teacher_view as select * from course where id>3;#删除视图
drop view teacher_view;

三、触发器

使用触发器可以定制用户对表增删改操作时前后的行为。

# 插入记录前触发
delimiter //
create trigger tri_before_insert_t1 before insert on t1 for each row
begin#如果新插入的数据success字段值为noif NEW.success = 'no' #向t2插入记录then insert t2 values(NEW.id,NEW.success) ; end if ; 
end//
delimiter ;# 插入后
delimiter //
create trigger tri_after_insert_t1 after insert on t1 for each row
begin#NEW表示即将插入的记录#如果新插入的数据success字段值为noif NEW.success = 'no' #向t2插入记录then insert t2 values(NEW.id,NEW.success) ; end if ; 
end//
delimiter ;#OLD表示即将删除的记录
# 删除前
delimiter //
create trigger tri_before_delete_t1 before delete on t1 for each row
begin......
end//
delimiter ;# 删除后
delimiter //
create trigger tri_after_delete_t1 after delete on t1 for each row
begin......
end//
delimiter ;# 更新前
delimiter //
create trigger tri_before_update_t1 before update on t1 for each row
begin......
end//
delimiter ;# 更新后
delimiter //
create trigger tri_after_update_t1 after update on t1 for each row
begin......
end//
delimiter ;#删除触发器
drop trigger tri_after_insert_cmd;

四、存储过程

存储过程包含了一系列可执行的sql语句,存储过程存放于MySQL中,通过调用它的名字可以执行其内部的一堆sql。
存储过程的优点是:用于替代程序写的SQL语句,实现程序与sql解耦;基于网络传输,传别名的数据量小,而直接传sql数据量大。
存储过程的缺点是:不便于扩展。

#无参存储过程
delimiter //
create procedure p1()
BEGINselect * from t1;insert t1(name) values("aaa");
END //
delimiter ;#在mysql中调用
call p1() #在python中调用
cursor.callproc('p1') 
print(cursor.fetchall())
#有参存储过程
delimiter //
#in声明的变量只能作为输入,out声明的变量只能作为输出,inout声明的变量可以作为输入或者输出
create procedure p1(in n1 int,out n2 int,inout n3 int)
BEGINselect * from t1 where id>n1 and id<n3;set n2=100;set n3=200;
END //
delimiter ;#在mysql中调用
set @res=0;
set @r=5;
call p1(3,@res,@r);
select @res;
select @r;
#可以看到res和r的值变为了100和200,而存储过程查询到了id为4的记录。#在python中调用
cursor.callproc('p1',(3,0,10))
#查看存储过程的查询结果
print(cursor.fetchall())
cursor.execute('select @_p1_0,@_p1_1,@_p1_2;')
#查看使用到的三个变量值
print(cursor.fetchall())

删除存储过程:drop procedure proc_name;

五、函数

mysql有许多内置函数,这里介绍一下date_format的使用方法。
date_format用于格式化时间。

select date_format('2009-10-04 22:23:00', '%Y-%m-%d %H:%i:%s');
<<<'2009-10-04 22:23:00'

自定义函数:

delimiter //
create function f1(i1 int,i2 int)
returns int
BEGINdeclare num int;set num = i1 + i2;return(num);
END //
delimiter ;

函数中不能写sql语句,函数仅仅是一个功能的集合,如果向我在begin和end中间写sql语句要使用存储过程。

删除函数:drop function func_name;
使用函数:
select f1(1,2) into @res;
select @res;
在查询时使用:select f1(11,id) ,name from t2;

六、流程控制

#条件语句
delimiter //
CREATE PROCEDURE proc_if ()
BEGINdeclare i int default 0;if i = 1 THENSELECT 1;ELSEIF i = 2 THENSELECT 2;ELSESELECT 7;END IF;
END //
delimiter ;
#while循环
delimiter //
CREATE PROCEDURE proc_while ()
BEGINDECLARE num INT ;SET num = 0 ;WHILE num < 10 DOSELECT num ;SET num = num + 1 ;END WHILE ;
END //
delimiter ;#repeat循环
delimiter //
CREATE PROCEDURE proc_repeat ()
BEGINDECLARE i INT ;SET i = 0 ;repeatselect i;set i = i + 1;until i >= 5end repeat;
END //
delimiter ;

七、数据库连接池

import pymysqlfrom DBUtils.PooledDB import PooledDB
POOL = PooledDB(creator=pymysql,  # 使用链接数据库的模块maxconnections=6,  # 连接池允许的最大连接数,0和None表示不限制连接数mincached=2,  # 初始化时,链接池中至少创建的空闲的链接,0表示不创建maxcached=5,  # 链接池中最多闲置的链接,0和None不限制maxshared=3,  # 链接池中最多共享的链接数量,0和None表示全部共享。PS: 无用,因为pymysql和MySQLdb等模块的 threadsafety都为1,所有值无论设置为多少,_maxcached永远为0,所以永远是所有链接都共享。blocking=True,  # 连接池中如果没有可用连接后,是否阻塞等待。True,等待;False,不等待然后报错maxusage=None,  # 一个链接最多被重复使用的次数,None表示无限制setsession=[],  # 开始会话前执行的命令列表。ping=0,# ping MySQL服务端,检查是否服务可用。host='127.0.0.1',port=3306,user='root',password='123',database='yk',charset='utf8',autocommit=True #自动提交
)def func():# 检测当前正在运行连接数的是否小于最大链接数,如果不小于则:等待或报raise TooManyConnections异常# 否则# 则优先去初始化时创建的链接中获取链接 SteadyDBConnection。# 然后将SteadyDBConnection对象封装到PooledDedicatedDBConnection中并返回。# 如果最开始创建的链接没有链接,则去创建一个SteadyDBConnection对象,再封装到PooledDedicatedDBConnection中并返回。# 一旦关闭链接后,连接就返回到连接池让后续线程继续使用。conn = POOL.connection()print( '链接被拿走了', conn._con)print( '池子里目前有', POOL._idle_cache, '\r\n')cursor = conn.cursor()cursor.execute('select * from user')result = cursor.fetchall()print(result)conn.close()if __name__ == '__main__':func()

相关文章:

mysql数据库(六)pymysql、视图、触发器、存储过程、函数、流程控制、数据库连接池

pymysql、视图、触发器、存储过程、函数、流程控制、数据库连接池 文章目录 pymysql、视图、触发器、存储过程、函数、流程控制、数据库连接池一、pymysql二、视图三、触发器四、存储过程五、函数六、流程控制七、数据库连接池 一、pymysql 可以使用pip install pymysql安装py…...

RFdiffusion EuclideanDiffuser类解读

EuclideanDiffuser 是 RFdiffusion 中的一个关键类,专门设计用于对**三维空间中的点(如蛋白质的原子坐标)**进行扩散处理。它通过逐步向这些点添加噪音来实现扩散过程,从而为扩散模型提供输入数据,并通过逆扩散还原这些数据。 get_beta_schedule函数源代码 def get_beta…...

Flutter实现气泡提示框学习

前置知识点学习 GlobalKey GlobalKey 是 Flutter 中一个非常重要的概念&#xff0c;它用于唯一标识 widget 树中的特定 widget&#xff0c;并提供对该 widget 的访问。这在需要跨越 widget 树边界进行交互或在 widget 树重建时保持状态时尤其有用。 GlobalKey 的作用 唯一标…...

vue3 路由守卫

在Vue 3中&#xff0c;路由守卫是一种控制和管理路由跳转的机制。它允许你在执行导航前后进行一些逻辑处理&#xff0c;比如权限验证、数据预取等&#xff0c;从而增强应用的安全性和效率。路由守卫分为几种不同的类型&#xff0c;每种类型的守卫都有其特定的应用场景。 其实路…...

【MATLAB源码-第218期】基于matlab的北方苍鹰优化算法(NGO)无人机三维路径规划,输出做短路径图和适应度曲线.

操作环境&#xff1a; MATLAB 2022a 1、算法描述 北方苍鹰优化算法&#xff08;Northern Goshawk Optimization&#xff0c;简称NGO&#xff09;是一种新兴的智能优化算法&#xff0c;灵感来源于北方苍鹰的捕猎行为。北方苍鹰是一种敏捷且高效的猛禽&#xff0c;广泛分布于北…...

如何控制自己玩手机的时间?两台苹果手机帮助自律

对一些人来说&#xff0c;被智能手机“绑架”是一件心甘情愿的事&#xff0c;和它相处的一天中&#xff0c;不必面对现实的压力&#xff0c;它就像个“舒适区”。这是因为在使用手机的过程中&#xff0c;应用程序&#xff08;尤其是游戏和社交媒体应用&#xff09;会不断刺激大…...

【java-Neo4j 5开发入门篇】-最新Java开发Neo4j

系列文章目录 前言 上一篇文章讲解了Neo4j的基本使用&#xff0c;本篇文章对Java操作Neo4j进行入门级别的阐述&#xff0c;方便读者快速上手对Neo4j的开发。 一、开发环境与代码 1.docker 部署Neo4j #这里使用docker部署Neo4j,需要镜像加速的需要自行配置 docker run --name…...

Python的3D可视化库 - vedo (1)简介和模块功能概览

文章目录 1. vedo和它支持的功能简介1.1 安装vedo1.2 命令行接口1.3 导出3D文件1.4 文件格式转换 2. vedo模块功能概览2.1 绘制和渲染visual 管理可视化、对象及其属性的显示的基类plotter 3D渲染colors 定义和显示颜色dolfin FEniCS/Dolfin库的支持 2.2 图形数据管理mesh 多边…...

全面解析:HTML页面的加载全过程(一)--输入URL地址,与服务器建立连接

用户输入URL地址&#xff0c;与服务器建立连接 用户在浏览器地址栏输入一个URL 浏览器开始执行以下三步操作操作&#xff1a;url解析、DNS查询、TCP连接 第一步&#xff1a;URL解析 什么是URL&#xff1f; URL(Uniform Resource Locator&#xff0c;统一资源定位符)是互联网…...

elasticsearch的倒排索引是什么?

大家好&#xff0c;我是锋哥。今天分享关于【elasticsearch的倒排索引是什么&#xff1f;】面试题。希望对大家有帮助&#xff1b; elasticsearch的倒排索引是什么&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 倒排索引&#xff08;Inverted Index&a…...

Ubuntu VNC Session启动chromium和firefox报错

问题描述 VNC客户端连接到Ubuntu Server后&#xff0c;启动chromium和firefox时报错&#xff1a; $ chromium [348564:348564:1117/102143.085649:ERROR:ozone_platform_x11.cc(244)] Missing X server or $DISPLAY [348564:348564:1117/102143.085732:ERROR:env.cc(258)] Th…...

【Tealscale + Headscale + 自建服务器】异地组网笔记

文章目录 效果为什么要用 Headscale云服务器安装 Headscale配置 config.yaml创建反向代理搭建管理 UI授权管理 UI添加互联设备参考 效果 首先是连接情况&#xff0c;双端都连接上自建的 Headscale&#xff0c; 手机使用移动流量&#xff0c;测试一下 ping 值 再试试进入游戏 可…...

C++ 编程基础(8)模版 | 8.2、函数模版

文章目录 一、函数模版1、声明与定义2、模版参数3、模板的实例化3.1、隐式实例化3.2、显示实例化 4、模版的特化5、注意事项6、总结 前言&#xff1a; C 函数模板是一种强大的特性&#xff0c;它允许程序员编写与类型无关的代码。通过使用模板&#xff0c;函数或类可以处理不同…...

Android Studio音频视频播放器课程设计

这个项目适合刚刚学习Android studio的初学者&#xff0c;实现音视频的基本播放功能&#xff0c;各项功能的页面都做的比较简单&#xff0c;特别适用于初学者&#xff0c;其特点在于本项目抛开了各种花里胡哨的制作&#xff0c;以最接近初学者的样式画面呈现&#xff0c;完全不…...

速盾:CDN是否支持屏蔽IP?

CDN&#xff08;内容分发网络&#xff09;是一种用于提高网站性能和可靠性的技术&#xff0c;通过将内容分发到距离终端用户更近的节点&#xff0c;减少了数据传输的延迟并提高了用户体验。在CDN中&#xff0c;屏蔽IP是一项重要的功能&#xff0c;可以帮助网站屏蔽无效或恶意请…...

机器学习—学习曲线

学习曲线是帮助理解学习算法如何工作的一种方法&#xff0c;作为它所拥有的经验的函数。 绘制一个符合二阶模型的学习曲线&#xff0c;多项式或二次函数&#xff0c;画出交叉验证错误Jcv&#xff0c;以及Jtrain训练错误&#xff0c;所以在这个曲线中&#xff0c;横轴将是Mtrai…...

在 macOS 和 Linux 中,波浪号 `~`的区别

文章目录 1、在 macOS 和 Linux 中&#xff0c;波浪号 ~macOS示例 Linux示例 区别总结其他注意事项示例macOSLinux 结论 2、root 用户的主目录通常是 /root解释示例切换用户使用 su 命令使用 sudo 命令 验证当前用户总结 1、在 macOS 和 Linux 中&#xff0c;波浪号 ~ 在 macO…...

【Java】实战:多数元素

一、题目描述 给定一个大小为 n 的数组 nums &#xff0c;返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的&#xff0c;并且给定的数组总是存在多数元素。 示例 1&#xff1a; 输入&#xff1a;nums [3,2,3] 输出&#x…...

一文解决Latex中的eps报错eps-converted-to.pdf not found: using draft setting.

在使用Vscode配的PDFLatex编译IEEE TII的Latex模板时&#xff0c;出现eps文件不能转换为pdf错误&#xff0c;看了几十篇方法都没用&#xff0c;自己研究了半天终于可以正常运行了。主要原因还是Settings.JSON中的PDFLatex模块缺少&#xff1a;"--shell-escape", 命令…...

计算光纤色散带来的相位移动 matlab

需要注意的地方 1.以下内容纯属个人理解&#xff0c;很有可能不准确&#xff0c;请大家仅做参考 2.光速不要直接用3e8 m/s&#xff0c;需要用精确的2.9979.... 3.光的频率无论在真空还是光纤(介质)都是不变的&#xff0c;是固有属性&#xff0c;但是波长lambdac/f在不同的介…...

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站&#xff0c;会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后&#xff0c;网站没有变化的情况。 不熟悉siteground主机的新手&#xff0c;遇到这个问题&#xff0c;就很抓狂&#xff0c;明明是哪都没操作错误&#x…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

【Linux】shell脚本忽略错误继续执行

在 shell 脚本中&#xff0c;可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行&#xff0c;可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令&#xff0c;并忽略错误 rm somefile…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍

文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结&#xff1a; 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析&#xff1a; 实际业务去理解体会统一注…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

2023赣州旅游投资集团

单选题 1.“不登高山&#xff0c;不知天之高也&#xff1b;不临深溪&#xff0c;不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)

Aspose.PDF 限制绕过方案&#xff1a;Java 字节码技术实战分享&#xff08;仅供学习&#xff09; 一、Aspose.PDF 简介二、说明&#xff08;⚠️仅供学习与研究使用&#xff09;三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

无人机侦测与反制技术的进展与应用

国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机&#xff08;无人驾驶飞行器&#xff0c;UAV&#xff09;技术的快速发展&#xff0c;其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统&#xff0c;无人机的“黑飞”&…...

纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join

纯 Java 项目&#xff08;非 SpringBoot&#xff09;集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...

LRU 缓存机制详解与实现(Java版) + 力扣解决

&#x1f4cc; LRU 缓存机制详解与实现&#xff08;Java版&#xff09; 一、&#x1f4d6; 问题背景 在日常开发中&#xff0c;我们经常会使用 缓存&#xff08;Cache&#xff09; 来提升性能。但由于内存有限&#xff0c;缓存不可能无限增长&#xff0c;于是需要策略决定&am…...