热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发笔记:模拟sql实现对员工列表的增删改查

篇首语:本文由编程笔记#小编为大家整理,主要介绍了模拟sql实现对员工列表的增删改查相关的知识,希望对你有一定的参考价值。

篇首语:本文由编程笔记#小编为大家整理,主要介绍了模拟sql实现对员工列表的增删改查相关的知识,希望对你有一定的参考价值。



现需要对这个员工信息文件,实现增删改查操作
#
# 可进行模糊查询,语法至少支持下面3种:
#   
#   select * from staff_table where dept = "IT"
# select * from staff_table where enroll_date like "2013"
# 查到的信息,打印后,最后面还要显示查到的条数
# 可创建新员工纪录,以phone做唯一键,staff_id需自增
# 可删除指定员工信息纪录,输入员工id,即可删除
# 可修改员工信息,语法如下:
#   UPDATE staff_table SET dept="Market" WHERE where dept = "IT"
思维导图

技术分享图片
流程分析

第一部分:SQL解析



  • 1.接收用户SQL

    • 判断用户输入是否为SQL



  • 2.SQL解析主函数sql_parse

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

      • insert_parse

      • delete_parse

      • update_parse

      • select_parse



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

    • 解析SQL语句中的多条件

      • where_parse

      • three_parse



    • 返回解析后的SQL




第二部分:SQL执行



  • 1.接收解析后的SQL



  • 2.SQL执行主函数sql_action



    • 分发SQL给对应函数来执行

      • insert

      • delete

      • update

      • select



    • 执行SQL语句时的多条件

      • where_action

      • logic_action

      • limit_action

      • search_action



    • 返回执行SQL的结果。

    • 代码




1 import os
2 #第一部分sql解析
3 def sql_parsing(sql):
4 ‘‘‘
5 把sql字符串切分提取命令信息,分发给函数去解析
6 :param sql:
7 :return:
8 ‘‘‘
9 # sql命令操作 解析函数的字典 根据用户的命令来找相对应的函数
10 parsing_func={
11 insert:increase_parsing, #增
12 delete:deleting_parsing, #删
13 update:reform_parsing, #改
14 select:check_parsing, #查
15
16 }
17 print(sql str is %s %sql) #打印用户输入的sql
18 sql_l=sql.split( ) #按空格切分 赋值给列表
19 func=sql_l[0] #取出用户的sql命名
20 res=‘‘
21 if func in parsing_func: #判断用户的命令 是否在pares_func里,不再返回空
22 res=parsing_func[func](sql_l) #把切分后的用户列表传人sql对应的函数里
23 res=parsing_func[func](sql_l) #把切分后的用户列表传人sql对应的函数里
24 return res
25
26 def increase_parsing(sql_l):
27 ‘‘‘
28 增加功能
29 :param sql:
30 :return:
31 ‘‘‘
32 sql_dic={
33 func:insert,
34 delete: [], # delete选项,留出扩展
35 into: [], # 表名
36 values: [], # filter条件
37
38 }
39 return handle_parsing(sql_l,sql_dic)
40
41
42
43 def reform_parsing(sql_l):
44 ‘‘‘
45 修改功能
46 :param sql:
47 :return:
48 ‘‘‘
49 sql_dic={
50 func:update,
51 update: [], # delete选项,留出扩展
52 set: [], # 表名
53 where: [], # filter条件
54
55 }
56 return handle_parsing(sql_l,sql_dic)
57
58
59
60 def deleting_parsing(sql_l):
61 ‘‘‘
62 删除功能
63 :param sql:
64 :return:
65 ‘‘‘
66 sql_dic={
67 func:delete,
68 delete: [], # delete选项,留出扩展
69 from: [], # 表名
70 where: [], # filter条件
71
72 }
73 return handle_parsing(sql_l,sql_dic)
74
75
76 def check_parsing(sql_l):
77 ‘‘‘
78
79 :param sql:
80 :return:
81 ‘‘‘
82 sql_dic={
83 func:select,
84 select: [], # 查询字段
85 from: [], # 数据库.表
86 where: [], # 条件
87 limit: [], # 条件,限制
88
89 }
90
91 return handle_parsing(sql_l,sql_dic)
92
93 def handle_parsing(sql_l,sql_dic): #解析sql
94 ‘‘‘
95 执行sql解析操作,返回sql_dic
96 :param sql_l:
97 :param sql_dic:
98 :return:
99 ‘‘‘
100
101 tag=False #设置警报
102 for item in sql_l: #for循环体 控制用户的sql列表
103 if tag and item in sql_dic: #if判断警报是否是真,并且用户sql的条件 在条件select语句字典里面,则关闭警报
104 tag=False # tag为假,关闭警报
105 if not tag and item in sql_dic: #判断警报没有拉响 并且用户sql的条件 在条件select语句字典里面
106 tag=True #警报拉响
107 key=item #
108 continue
109 if tag:
110 sql_dic[key].append(item) #for循环体取出的值做判断,成立把值添加到条件对应的字典里
111 if sql_dic.get(where):
112 sql_dic[where]=where_parsing(sql_dic.get(where)) #调用where_parse函数 把整理好的用户sql的where语句 覆盖之前没整理好的
113
114 return sql_dic #返回解析结果到字典里
115
116 def where_parsing(where_l):
117 ‘‘‘
118 :param where_l:
119 :return:
120 ‘‘‘
121 res=[] #定义空列表 返回return的值放进列表里
122 key=[and,or,not] #
123 char=‘‘ #拼接好的字符串
124 for i in where_l: #循环体
125 if len(i) ==0:continue #判断长度如果是0跳出本次循环
126 if i in key: #判断i的值里是不是有kuy
127 if len(char) !=0: #char的长度必须是大于0
128 char=three_parsing(char)
129 res.append(char)
130 res.append(i)
131 char=‘‘
132 else:char+=i
133
134 else:
135 char=three_parsing(char)
136 res.append(char)
137 return res
138
139 def three_parsing(exp_str):
140 ‘‘‘
141 将每一个小的过滤条件如,name>=1转换成[name,>=,1]
142 :param exp_str:
143 :return:
144 ‘‘‘
145 key=[>,<,=]
146 res=[]
147 char=‘‘
148 opt=‘‘
149 tag=False
150 for i in exp_str:
151 if i in key:
152 tag=True
153 if len(char)!=0:
154 res.append(char)
155 char=‘‘
156 opt+=i
157 if not tag:
158 char+=i
159 if tag and i not in key:
160 tag=False
161 res.append(opt)
162 opt=‘‘
163 char+=i
164 else:
165 res.append(char)
166 if len(res) ==1:
167 res=res[0].split(like)
168 res.insert(1,like)
169
170 return res #返回res列表结果
171
172
173
174
175
176
177 # siq执行
178 def sql_perform(sql_dic):
179 ‘‘‘
180 :param sql:
181 :return:
182 ‘‘‘
183 return sql_dic.get(func)(sql_dic)
184
185 def insert(sql):
186 ‘‘‘
187
188 :param sql:
189 :return:
190 ‘‘‘
191 print(insert %s %sql_dic)
192 db,table=sql_dic.get(into)[0].split(.)
193 with open(%s/%s %(db,table),ab+) as fh:
194 offs=-100
195 while True:
196 fh.seek(offs,2)
197 lines=fh.readlines()
198 if len(lines)>1:
199 last=lines[-1]
200 break
201
202 offs *=2
203 last=last.decode(encoding=utf-8)
204 last_id=int(last.split(,)[0])
205 new_id=last_id+1
206 record=sql_dic.get(values)[0].split(,)
207 record.insert(0, str(new_id))
208 record_str = ,.join(record) + \\n
209 fh.write(bytes(record_str, encoding=utf-8)) # 把添加 id后的用户想添加的sql 用bytes写入文件
210 fh.flush()
211 return [[insert successful]]
212
213 def update(sql_dic):
214 #update db1.emp set id=sb where name like alex
215 db,table=sql_dic.get(update)[0].split(.)
216 set=sql_dic.get(set)[0].split(,)
217 set_l=[]
218 for i in set:
219 set_l.append(i.split(=))
220 bak_file=table+_bak
221 with open("%s/%s" %(db,table),r,encoding=utf-8) as r_file,222 open(%s/%s %(db,bak_file),w,encoding=utf-8) as w_file:
223 update_count=0
224 for line in r_file:
225 title="id,name,age,phone,dept,enroll_date"
226 dic=dict(zip(title.split(,),line.split(,)))
227 filter_res=logic_action(dic,sql_dic.get(where))
228 if filter_res:
229 for i in set_l:
230 k=i[0]
231 v=i[-1].strip("")
232 print(k v %s %s %(k,v))
233 dic[k]=v
234 print(change dic is %s %dic)
235 line=[]
236 for i in title.split(,):
237 line.append(dic[i])
238 update_count+=1
239 line=,.join(line)
240 w_file.write(line)
241
242 w_file.flush()
243 os.remove("%s/%s" % (db, table))
244 os.rename("%s/%s" %(db,bak_file),"%s/%s" %(db,table))
245 return [[update_count],[update successful]]
246
247 def delete(sql):
248 db,table=sql_dic.get(from)[0].split(.)
249 bak_file=table+_bak
250 with open("%s/%s" %(db,table),r,encoding=utf-8) as r_file,251 open(%s/%s %(db,bak_file),w,encoding=utf-8) as w_file:
252 del_count=0
253 for line in r_file:
254 title="id,name,age,phone,dept,enroll_date"
255 dic=dict(zip(title.split(,),line.split(,)))
256 filter_res=logic_action(dic,sql_dic.get(where))
257 if not filter_res:
258 w_file.write(line)
259 else:
260 del_count+=1
261 w_file.flush()
262 os.remove("%s/%s" % (db, table))
263 os.rename("%s/%s" %(db,bak_file),"%s/%s" %(db,table))
264 return [[del_count],[delete successful]]
265
266 def select(sql_dic):
267 ‘‘‘
268 :param sql_dic:
269 :return:
270 ‘‘‘
271 db,table=sql_dic.get(from)[0].split(.) # 切分出库名和表名,就是文件路径
272 fh=open("%s/%s" % (db,table),r, encoding=utf-8) # 打开文件 根据取到的路径
273 filter_res=where_action(fh,sql_dic.get(where))
274 fh.close()
275 limit_res=limit_action(filter_res,sql_dic.get(limit)) #定义limit执行函数,限制行数
276 # for record in limit_res: # 循环打印 显示用户sql limit的执行结果
277 # print(limit res is %s %record)
278
279 #lase:select
280 search_res=search_action(limit_res,sql_dic.get(select)) #定义select执行函数
281 # for record in search_res: # 循环打印 显示用户sql select的执行结果
282 # print(select res is %s %record)
283
284 return search_res
285
286
287
288 def logic_action(dic, where_l):
289 ‘‘‘
290 用户sql select的where多条件 执行对比文件内容
291 文件内容 跟所有的 where_l 的条件比较
292 :param dic:
293 :param where_l:
294 :return:
295 ‘‘‘
296 # print(from logic_action %s %dic) #from logic_action {id: 23, name: 翟超群, age: 24, phone: 13120378203, dept: 运维, enroll_data: 2013-3-1\\n}
297 # print(---- %s %where_l) #[[name, like, ], or, [id, <=, 4]]
298 res = [] # 存放 bool值 结果的空列表
299 # where_l=[[name, like, ], or, [id, <=, 4]]
300 for exp in where_l: # 循环where条件列表,跟dic做比较
301 # dic与exp做bool运算
302 if type(exp) is list: # 只留下 where_l列表里 相关的条件
303 # 如果是列表 做bool运算 #[[name, like, ]
304 exp_k, opt, exp_v = exp # 匹配 一个where条件列表的格式
305 if exp[1] == =: # 如果 列表的运算符是 =
306 opt = "%s=" % exp[1] # 用字符串拼接出 两个 ==
307 if dic[exp_k].isdigit(): # 判断是否数字 用户的条件是否对应文件内容(字典)
308 dic_v = int(dic[exp_k]) # 文件内容的数字 转成整形 做比较
309 exp_v = int(exp_v) # where_l列表的数字 转成整形 做比较
310 else:
311 dic_v = "‘%s‘" % dic[exp_k] # 不是数字的时候 存取出来
312 if opt != like: # 如果运算符 不是 like
313 exp = str(eval("%s%s%s" % (dic_v, opt, exp_v))) # 转成字符串(逻辑判断后是bool值):做逻辑判断:文件数字,运算符,用户数字
314 else: # 如果 运算符位置是 like
315 if exp_v in dic_v: # 判断 sql里like的值 是否在 文件内容里
316 exp = True
317 else:
318 exp = False
319 res.append(exp) # [True,or,False,or,true]
320
321 # print(---------- %s %res)
322 res = eval(" ".join(res)) # 把bool值列表转成字符串 然后再做逻辑判断 结果是bool值
323 return res # 返回 res结果
324
325 def limit_action(filter_res,limit_l): #执行limit条件 限制行数
326 res=[] #最后的返回值列表
327 if len(limit_l) != 0: #判断 用户sql 是否有 limit条件
328 index=int(limit_l[0]) #取出 用户sql limit条件的数字
329 res=filter_res[0:index]
330 else: #如果 用户sql 没有 limit条件 就整个返回
331 res=filter_res
332 return res #返回最后的sql结果
333
334 def search_action(limit_res,select_l): #执行select执行函数
335 res=[] #最后的返回值列表
336 fileds_l = []
337 title = "id,name,age,phone,dept,enroll_data" #title = select的条件
338 if select_l[0] == * : #判断 如果 用户sql 的select 条件是 *
339 fields_l=title.split(,) #用户sql 的select 条件是 * ,则匹配所有条件
340 res=limit_res #如果 用户sql 的select 条件是 * 则返回全部
341 else: #判断 如果用户sql的select条件不是 * ,提取用户的select语句条件
342 for record in limit_res: #循环 匹配好的where语句和limit语句的结果
343 dic=dict(zip(title.split(,),record)) #每条记录都对应 select条件,生成字典
344 r_l=[] #存放用户sql的select条件
345 fields_l=select_l[0].split(,) #取出用户sql 的select条件
346 for i in fields_l: #循环用户sql的select条件,区分多条件,id,name
347 r_l.append(dic[i].strip()) #把用户sql的select多条件 加入 r_l列表
348 res.append(r_l) #把r_l列表 加入res
349
350 return (fields_l,res) #返回用户sql的select条件,selcet执行结果
351
352 def where_action(fh,where_l): #执行where条件语句 where_l=where的多条件解析后的列表
353 #id,name,age,phone,dept,enroll_data
354 #10,吴东杭,21,17710890829,运维,1995-08-29
355 #[id>7, and, id<10, or, namelike]
356
357 # print(in where_action \\033[41;1m%s\\033[0m %where_l)
358 res=[] #定义最后返回值的列表
359 logic_l=[and,or,not] #定义逻辑运算符
360 title="id,name,age,phone,dept,enroll_data" #定义好表文件内容的标题
361 if len(where_l) != 0: #判断用户sql 是否有where语句
362 for line in fh: #循环 表文件
363 dic=dict(zip(title.split(,),line.split(,))) #一条记录 让标题和文件内容一一对应
364 #逻辑判断
365 logic_res=logic_action(dic,where_l) #让 logic_action函数来操作对比
366 if logic_res: #如果逻辑判断为True
367 res.append(line.split(,)) #加入res
368 else:
369 res=fh.readlines() #用户sql 没有where语句,则返回表文件所有内容
370
371 # print(>>>>>>>> %s %res)
372 return res #返回执行 where 后的结果
373
374
375 if __name__==__main__: #主函数
376 while True:
377 sql=input("sql>:").strip() #用户输入sql 命令
378 if sql ==exit: #exit退出登录
379 break
380 if len(sql)==0: #用户输入为空字符继续输入
381 continue
382
383 sql_dic=sql_parsing(sql) #用户输入sql转成机构化字典
384 if len(sql_dic) == 0:continue #
385 res=sql_perform(sql_dic) #执行结果赋值给src
386 print(\\033[43;1m%s\\033[0m % res[0])
387 for i in res[-1]:
388 print(i)
389
390 ‘‘‘
391 测试执行 select语句
392 select * from db.emp
393 select * from db.emp limit 2
394 select * from db.emp where name like 李 or id <= 9 or id = 24 limit 9
395 select id,name from db.emp where name like 李 or id <= 9 or id = 24 limit 9
396
397 测试执行 insert语句
398 insert into db.emp values gyf,30,18500841678,运维,2007-8-1
399
400 测试执行 delete语句
401 delete from db.emp where id>47
402
403 测试执行 update语句
404 update db.emp set gyf=haha where id=47
405 ‘‘‘

 

























推荐阅读
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • ALTERTABLE通过更改、添加、除去列和约束,或者通过启用或禁用约束和触发器来更改表的定义。语法ALTERTABLEtable{[ALTERCOLUMNcolu ... [详细]
  • Explain如何助力SQL语句的优化及其分析方法
    本文介绍了Explain如何助力SQL语句的优化以及分析方法。Explain是一个数据库SQL语句的模拟器,通过对SQL语句的模拟返回一个性能分析表,从而帮助工程师了解程序运行缓慢的原因。文章还介绍了Explain运行方法以及如何分析Explain表格中各个字段的含义。MySQL 5.5开始支持Explain功能,但仅限于select语句,而MySQL 5.7逐渐支持对update、delete和insert语句的模拟和分析。 ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • 也就是|小窗_卷积的特征提取与参数计算
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了卷积的特征提取与参数计算相关的知识,希望对你有一定的参考价值。Dense和Conv2D根本区别在于,Den ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • 本文讨论了如何使用IF函数从基于有限输入列表的有限输出列表中获取输出,并提出了是否有更快/更有效的执行代码的方法。作者希望了解是否有办法缩短代码,并从自我开发的角度来看是否有更好的方法。提供的代码可以按原样工作,但作者想知道是否有更好的方法来执行这样的任务。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • web.py开发web 第八章 Formalchemy 服务端验证方法
    本文介绍了在web.py开发中使用Formalchemy进行服务端表单数据验证的方法。以User表单为例,详细说明了对各字段的验证要求,包括必填、长度限制、唯一性等。同时介绍了如何自定义验证方法来实现验证唯一性和两个密码是否相等的功能。该文提供了相关代码示例。 ... [详细]
  • 第四章高阶函数(参数传递、高阶函数、lambda表达式)(python进阶)的讲解和应用
    本文主要讲解了第四章高阶函数(参数传递、高阶函数、lambda表达式)的相关知识,包括函数参数传递机制和赋值机制、引用传递的概念和应用、默认参数的定义和使用等内容。同时介绍了高阶函数和lambda表达式的概念,并给出了一些实例代码进行演示。对于想要进一步提升python编程能力的读者来说,本文将是一个不错的学习资料。 ... [详细]
  • 本文介绍了在处理不规则数据时如何使用Python自动提取文本中的时间日期,包括使用dateutil.parser模块统一日期字符串格式和使用datefinder模块提取日期。同时,还介绍了一段使用正则表达式的代码,可以支持中文日期和一些特殊的时间识别,例如'2012年12月12日'、'3小时前'、'在2012/12/13哈哈'等。 ... [详细]
author-avatar
heishi86188
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有