包含updatesetin的词条

http://www.itjxue.com  2023-01-20 00:46  来源:未知  点击次数: 

Mysql查询将查询的结果进行更新

有时候我们会不小心对一个大表进行了 update,比如说写错了 where 条件......

此时,如果 kill 掉 update 线程,那回滚 undo log 需要不少时间。如果放置不管,也不知道 update 会持续多久。

那我们能知道 update 的进度么?

实验

我们先创建一个测试数据库:

快速创建一些数据:

连续执行同样的 SQL 数次,就可以快速构造千万级别的数据:

查看一下总的行数:

我们来释放一个大的 update:

然后另起一个 session,观察 performance_schema 中的信息:

可以看到,performance_schema 会列出当前 SQL 从引擎获取的行数。

等 SQL 结束后,我们看一下 update 从引擎总共获取了多少行:

可以看到该 update 从引擎总共获取的行数是表大小的两倍,那我们可以估算:update 的进度 = (rows_examined) / (2 * 表行数)

??小贴士

information_schema.tables 中,提供了对表行数的估算,比起使用 select count(1) 的成本低很多,几乎可以忽略不计。

那么是不是所有的 update,从引擎中获取的行数都会是表大小的两倍呢?这个还是要分情况讨论的,上面的 SQL 更新了主键,如果只更新内容而不更新主键呢?我们来试验一下:

等待 update 结束,查看 row_examined,发现其刚好是表大小:

那我们怎么准确的这个倍数呢?

一种方法是靠经验:update 语句的 where 中会扫描多少行,是否修改主键,是否修改唯一键,以这些条件来估算系数。

另一种方法就是在同样结构的较小的表上试验一下,获取倍数。

这样,我们就能准确估算一个大型 update 的进度了。

sql 请教update语句in多个值时,进行多次更新

在数据库的操作中,更新数据,是很常见的情况。其中sql 请教update语句in多个值时,进行多次更新的方法为:

1、创建一个临时表,用于演示sqlserver语法中update更新修改使用方法。

2、创建另外一个临时表,用于演示如何将一个临时表的数据更新到另外一个临时表。

3、往临时表中插入几行测试数据,其中的Total栏位都不插入值。

4、查询临时表中的测试数据select * from #tblUpdate;select * from #tblTotal。

5、使用update更新临时表#tblUpdate中的Total结果,假设Total = num * price update #tblUpdate set Total = Num * Price。

6、再次查询临时表#tblUpdate的结果,可以看到之前为NULL的Total列都有值了。

注意事项:

SQL的核心部分相当于关系代数,但又具有关系代数所没有的许多特点,如聚集、数据库更新等。它是一个综合的、通用的、功能极强的关系数据库语言。

update语句中条件限制是不能用in语句的吗

一、要求

当然此表你在文件存储时可以这样表示

1,li,22,18230393840,IT,2013-06-01 现需要对这个员工信息文件,实现增删改查操作

1.?可进行模糊查询,语法至少支持下面3种:

1.?select?name,age?from?staff_table?where?age??22

2.?select??*?from?staff_table?where?dept?=?"IT"

3.?select??*?from?staff_table?where?enroll_date?like?"2013“

2.?可修改员工信息,语法如下:

1.?UPDATE?staff_table?SET?dept="Market"?WHERE?where?dept?=?"IT"

注意:以上需求,要充分使用函数,请尽你的最大限度来减少重复代码!

二、实现流程第一部分:SQL解析

1.接收用户SQL

判断用户输入是否为SQL

2.SQL解析主函数sql_parse

where_parse

three_parse

insert_parse

delete_parse

update_parse

select_parse

分发SQL给对应语句的函数来做解析

解析后交给handle_parse,来控制返回

解析SQL语句中的多条件

返回解析后的SQL

第二部分:SQL执行

1.接收解析后的SQL

2.SQL执行主函数sql_action

where_action

logic_action

limit_action

search_action

insert

delete

update

select

分发SQL给对应函数来执行

执行SQL语句时的多条件

返回执行SQL的结果

三、图解

代码:

#/usr/local/env?python

#_*_coding:utf-8_*_

#第一部分:sql解析

import?os

def?sql_parse(sql):?#用户输入sql?转成结构化的字典

????'''

????第一步:sql解析?流程

????1.收到?sql查询条件

????2.sql_parse?来分发要求给?select_parse

????3.select_parse?调用?handle_parse?解析sql

????4.handle_parse?返回解析sql后的结果?sql_dic?给?select_parse

????5.select_parse?把?sql_dic?返回给sql_parse

????sql_dic=sql_parse(sql)?#用户输入sql?转成结构化的字典sql_dic

????sql语句四种操作格式:insert?delete?update?select

????提取用户输入sql?的操作关键词?再进行分析和分发操作

????把sql字符串切分,提取命令信息,分发给具体解析函数去解析

????:param?sql:用户输入的字符串

????:return:返回字典格式sql解析结果

????'''

????#sql命令操作?解析函数的字典??根据用户的命令来找相对应的函数

????parse_func={

????????'insert':insert_parse,

????????'delete':delete_parse,

????????'update':update_parse,

????????'select':select_parse,

????}

????#print('用户输入?sql?str?is?:?%s'?%sql)?#打印用户输入的sql

????sql_l=sql.split('?')?#按空格切割用户sql?成列表?方便提取命令信息

????func=sql_l[0]?#取出用户的sql命令

????#判断用户输入的sql命令?是否在定义好的sql命令函数的字典里面,如果不在字典里面,则返回空

????res=''

????if?func?in?parse_func:

????????res=parse_func[func](sql_l)?#把切割后的?用户sql的列表?传入对应的sql命令函数里

????return?res

def?insert_parse(sql_l):

????'''

????定义insert语句的语法结构,执行sql解析操作,返回sql_dic

????:param?sql:sql按照空格分割的列表

????:return:返回字典格式的sql解析结果

????'''

????sql_dic={

????????'func':insert,?#函数名

????????'insert':[],???#insert选项,留出扩展

????????'into':[],?????#表名

????????'values':[],???#值

????}

????return?handle_parse(sql_l,sql_dic)

def?delete_parse(sql_l):

????'''

????定义delete语句的语法结构,执行sql解析操作,返回sql_dic

????:param?sql:sql按照空格分割的列表

????:return:返回字典格式的sql解析结果

????'''

????sql_dic?=?{

????????'func':?delete,

????????'delete':?[],??#?delete选项,留出扩展

????????'from':?[],??#?表名

????????'where':?[],??#?filter条件

????}

????return?handle_parse(sql_l,?sql_dic)

def?update_parse(sql_l):

????'''

????定义update语句的语法结构,执行sql解析操作,返回sql_dic

????:param?sql:sql按照空格分割的列表

????:return:返回字典格式的sql解析结果

????'''

????sql_dic?=?{

????????'func':?update,

????????'update':?[],??#?update选项,留出扩展

????????'set':?[],??#?修改的值

????????'where':?[],??#?filter条件

????}

????return?handle_parse(sql_l,?sql_dic)

def?select_parse(sql_l):

????'''

????定义select语句的语法结构,执行sql解析操作,返回sql_dic

????:param?sql:sql按照空格分割的列表

????:return:返回字典格式的sql解析结果

????'''

????#?print('from?in?the?select_parse?:\033[42;1m%s\033[0m'?%sql_l)

????#?select语句多种条件查询,列成字典,不同条件不同列表

????sql_dic={

????????'func':select,?#执行select语句

????????'select':[],?#查询字段

????????'from':[],???#数据库.表

????????'where':[],??#filter条件,怎么找

????????'limit':[],??#limit条件,限制

????}

????return?handle_parse(sql_l,sql_dic)

def?handle_parse(sql_l,sql_dic):?#专门做sql解析操作

????'''

????执行sql解析操作,返回sql_dic

????:param?sql_l:?sql按照空格分割的列表

????:param?sql_dic:?待填充的字典

????:return:?返回字典格式的sql解析结果

????'''

????#?print('sql_l?is?\033[41;1m%s\033[0m?\nsql_dic?is?\033[41;1m%s\033[0m'?%(sql_l,sql_dic))

????tag=False??#设置警报?默认是关闭False

????for?item?in?sql_l:??#循环?按空格切割用户sql的列表

????????if?tag?and?item?in?sql_dic:?#判断警报拉响是True?并且用户sql的条件?在条件select语句字典里面,则关闭警报

????????????tag=False?#关闭警报

????????if?not?tag?and?item?in?sql_dic:?#判断警报没有拉响?并且用户sql的条件?在条件select语句字典里面

????????????tag=True?#拉响警报

????????????key=item?#取出用户sql的条件

????????????continue?#跳出本次判断

????????if?tag:?#判断报警拉响

????????????sql_dic[key].append(item)?#把取出的用户sql?添加到?select语句多种条件对应的字典里

????if?sql_dic.get('where'):?#判断?用户sql?where语句

????????sql_dic['where']=where_parse(sql_dic.get('where'))?#['id4','and','id10']?#调用where_parse函数?把整理好的用户sql的where语句?覆盖之前没整理好的

????#?print('from?in?the?handle_parse?sql_dic?is?\033[43;1m%s\033[0m'?%sql_dic)

????return?sql_dic?#返回?解析好的?用户sql?字典

def?where_parse(where_l):?#['id','4','and','id','10']?---?#['id4','and','id10']

????'''

????分析用户sql?where的各种条件,再拼成合理的条件字符串

????:param?where_l:用户输入where后对应的过滤条件列表

????:return:

????'''

????res=[]??#存放最后整理好条件的列表

????key=['and','or','not']??#逻辑运算符

????char=''??#存放拼接时的字符串

????for?i?in?where_l:??#循环用户sql

????????if?len(i)?==?0?:continue??#判断?长度是0?就继续循环

????????if?i?in?key:

????????????#i为key当中存放的逻辑运算符

????????????if?len(char)?!=?0:??#必须?char的长度大于0

????????????????char=three_parse(char)??#把char字符串?转成列表的形式

????????????????res.append(char)??#把之前char的字符串,加入res?#char='id4'---char=['id','','4']

????????????????res.append(i)??#把用户sql?的逻辑运算符?加入res

????????????????char=''??#清空?char?,为了下次加入char到res时?数据不重复

????????else:

????????????char+=i??#'id4'?#除了逻辑运算符,都加入char?#char='id10'---char=['id','','4']

????else:

????????char?=?three_parse(char)??#?把char字符串?转成列表的形式

????????res.append(char)??#循环完成后?char里面有数据?,再加入到res里面

????#?['id4','and','id10']?---?#['id','','4','and','id','','10']

????#?print('from?in?the?where_parse?res?is?\033[43;1m%s\033[0m'?%?res)

????return?res??#返回整理好的?where语句列表

def?three_parse(exp_str):??#?把where_parse函数里面?char的字符串?转成字典

????'''

????将每一个小的过滤条件如,name=1转换成['name','=','1']

????:param?exp_str:条件表达式的字符串形式,例如'name=1'

????:return:

????'''

????key=['','','=']??#区分运算符

????res=[]???#定义空列表?存放最终值

????char=''??#拼接?值的字符串

????opt=''???#拼接?运算符

????tag=False???#定义警报

????for?i?in?exp_str:??#循环?字符串和运算符

????????if?i?in?key:??#判断?当是运算符时

????????????tag=True???#拉响警报

????????????if?len(char)?!=?0:??#判断char的长度不等于0时(方便添加连续运算符)才做列表添加

????????????????res.append(char)??#把拼接的字符串加入?res列表

????????????????char=''???#清空char?使下次循环不重复添加数据到res列表

????????????opt+=i????#把循环的运算符加入opt

????????if?not?tag:???#判断?警报没有拉响

????????????char+=i????#把循环的字符串加入?char

????????if?tag?and?i?not?in?key:?#判断?警报拉响(表示上次循环到运算符),并且本次循环的不是运算符

????????????tag=False??#关闭警报

????????????res.append(opt)??#把opt里面的运算符?加入res列表

????????????opt=''??#清空opt?使下次循环不重复添加数据到res列表

????????????char+=i?#把循环到的?字符串加入char

????else:

????????res.append(char)?#循环结束,把最后char的字符串加入res列表

????#新增解析?like的功能

????if?len(res)?==?1:??#判断?['namelike李']?是个整体

????????res=res[0].split('like')??#以like切分字符串

????????res.insert(1,'like')??#加入like字符串,因为上面切分的时候剔除了like

????#?print('three_parse?res?is?\033[43;1m%s\033[0m'?%?res)

????return?res??#返回res列表结果

#第二部分:sql执行

def?sql_action(sql_dic):?#接收用户输入的sql?的结构化的字典??然后执行sql

????'''

????从字典sql_dic提取命令,分发给具体的命令执行函数去执行

????执行sql的统一接口,内部执行细节对用户完全透明

????:param?sql_dic:

????:return:

????'''

????return?sql_dic.get('func')(sql_dic)?#接收用户sql,分发sql,执行命令

def?insert(sql_dic):

????print('insert?%s'?%sql_dic)

????db,table=sql_dic.get('into')[0].split('.')??#切分文件路径,相对应数据库,表

????with?open('%s/%s'?%(db,table),'ab+')?as?fh:??#安装上面的路径?打开文件?ab+模式

????????#?读出文件最后一行,赋值给last?配合+

????????offs?=?-100??#

????????while?True:

????????????fh.seek(offs,2)

????????????lines?=?fh.readlines()

????????????if?len(lines)1:

????????????????last?=?lines[-1]

????????????????break

????????????offs?*=?2

????????last=last.decode(encoding='utf-8')

????????last_id=int(last.split(',')[0])??#取出最后一行id号

????????new_id=last_id+1???#id号加1?实现id自增效果

????????#insert?into?db1.emp?values?alex,30,18500841678,运维,2007-8-1

????????record=sql_dic.get('values')[0].split(',')???#提取用户想要?添加的sql

????????record.insert(0,str(new_id))??#加入自增后的id?到用户sql的头部

????????#['26','alex','35','13910015353','运维','2005?-?06?-?27\n']

????????record_str=','.join(record)+'\n'??#把用户sql列表切成字符串

????????fh.write(bytes(record_str,encoding='utf-8'))??#把添加?id后的用户想添加的sql??用bytes写入文件

sql update set in

UPDATE tab a

SET beactive= '否'

FROM TABLE1

WHERE TABLE1.beactive IN (SELECT beactive FROM tab b )

(责任编辑:IT教学网)

更多

推荐FTP服务器文章