模拟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 ‘‘‘


时间: 2024-10-28 12:34:58

模拟sql实现对员工列表的增删改查的相关文章

列表的增删改查

列表的用法和字符串不一样,不要搞混了! 思维导图: 列表的增删改查: # [1,2,'c','dfas',True] #索引和切片. # li = [1,2,3,'af','re',4,'45'] # print(l[0]) # print(l[3]) # print(l[-1]) #切片: # print(li[0:3]) # print(li[2:5]) # print(li[0:5:2]) # print(li[-2::-2]) # print(li[5:0:-2]) #苑昊 # li =

列表的初识,列表的索引切片,列表的增删改查,列表的嵌套,元组的初识,range

1 内容总览 列表的初识 列表的索引切片 列表的增删改查 列表的嵌套 元组的初识(了解) 元组的简单应用(了解) range 2 具体内容 列表的初识 why: str: 存储少量的数据.切片出来全都是str类型,存储的数据单一. list:能储存大量的数据.包含不同类型的数据.且有顺序,有规律,可自己制作设计其中的数据,可修改 what:list l1 = [100, 'alex',True,[1, 2, 3]] 可承载任意数据类型,存储大量的数据. python常用的容器型数据类型. 列表是

Python列表的增删改查排

Python列表的增删改查排 一.列表的样子: a = ['q' , 'w' , 'e ', 'r','t'] a为列表名,[ ]为列表内容,' '为列表内的元素,'q'为a[0] 二.查(也称切片): print ( a[0] )          #取出列表中第一个元素 即:q print ( a[1:] )        #从第二个元素开始取到最后 即:['w', 'e','r', 't'] print ( a[1:3] )        #取出从第二个开始到第三个元素 即:['w','e

day5 列表的增删改查

1,列表的增删改查,其他操作.2,元祖.3,列表的嵌套操作.4,开一点dict. 昨日内容回顾: 字符串的方法:1,find通过元素找索引,可切片,找不到返回-12,index,找不到报错.3,split 由字符串分割成列表,默认按空格.4,captalize 首字母大写,其他字母小写.5,upper 全大写.6,lower 全小写.7,title,每个单词的首字母大写.8,startswith 判断以什么为开头,可以切片,整体概念.9,endswith 判断以什么为结尾,可以切片,整体概念.1

初识列表和列表的增删改查

列表初识 列表是一种容器型数据类型,可以储存大量的数据. 列表可储存的数据类型:元组-列表-字符串-bool-int 列表的索引和切片规则与字符串一样 列表的增删改查排序 增: 1.append 在尾部追加指定元素 list.append('添加元素') 2.insert 根据索引插入指定元素 list.insert(索引,'插入元素') 3.extend 以迭代的方式追加 list.extendd('追加元素') 删: 1.pop 按照索引值删除(有返回值) list.pop(索引值) 2.r

列表,元组 和列表的增删改查 还有range

1)rangerange(边界) 从0到边界range(start, end) 从start到endrange(start, end, step) 从start到end. 步长是step 遍历列表的时候可以使用range for i in range(len(list)): list[i] 2)什么是列表(list) lis=[内容,不限制类型] lst = list() #创建空列表 列表就是能装对象的对象 用[]表示,内部内容用,隔开 可以索引 切片 和 嵌套 3)列表的增删改查 新增: a

Vue电商后台管理系统项目第5篇-角色列表的增删改查&amp;&amp;角色授权

角色列表的增删改查 1.添加角色 先根据API文档编写接口: // 添加角色 export const addRolesApi = (data) => { return axios({ method: 'post', url: 'roles', data }) } 在角色组件内引用,然后给 添加角色 按钮绑定一个点击事件addRolesClick: <!-- 添加角色 --> <el-button type="success" plain @click=&quo

Sql Server xml 类型字段的增删改查

1.定义表结构 在MSSM中新建数据库表CommunicateItem,定义其中一个字段ItemContentXml 为xml类型 2.编辑表数据,新增一行,发现xml类型不能通过设计器录入数据. 需要写sql更新或插入. DECLARE @xml XML SET @xml=' <MyHobby> <MyCode>1</MyCode> <MyName>爬山</MyName> </MyHobby> <MyHobby> <

Python列表的增删改查

列表list的增删改查一.增:append().insert()方法1.append()方法:在末尾添加元素#szz = ['ab','jhj','nhy']#szz.append('msr')2.insert()方法:在指定位置添加元素或者列表#szz = ['ab','jhj','nhy']#szz1 = ['msr','mike']#szz.insert(0,'mark')#szz.insert(0,szz1)二.删:del.pop().remove().clear()1.del:可以删除