码迷,mamicode.com
首页 > 数据库 > 详细

模拟sql实现对员工列表的增删改查

时间:2017-12-22 11:14:53      阅读:235      评论:0      收藏:0      [点我收藏+]

标签:数字   param   技术   list   int   命名   相关   false   delete   

现需要对这个员工信息文件,实现增删改查操作
#
# 可进行模糊查询,语法至少支持下面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实现对员工列表的增删改查

标签:数字   param   技术   list   int   命名   相关   false   delete   

原文地址:http://www.cnblogs.com/Lollipop1/p/8084938.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!