【作业内容】
模拟sql执行过程,完成对特定表的增、删、改、查。
【作业分析】
随着现在信息量的增加,以及数据库提供的强大数据管理能力,数据库编程编程了IT开发者必备的技能之一。数据库开发者会预留数据库对外接口,以便开发人员来使用,通过这些接口,我们可以执行我们的查询、删除、更行、插入等sql语句,而我们的作业内容则是为了更好的了解sql语句执行的过程,调高自己的sql语句编写能力,也是想通过这个例子,对函数有进一步的了解,话不多少,代码如下:
keyword_list = ['from','into','update']
spr = ' '
def SearchAll(strlist,table_name):
'查询'
if 'where' in strlist:
Condition_query(strlist,table_name)
else:
Query(strlist,table_name)
def Delete(strlist,table_name):
'删除数据项'
temp_tablename = ''
index = 0
if 'where' not in strlist:
index,colName = GetTableItemNum(table_name)
f = open(table_name,'w')
f.write(colName)
f.close()
else:
temp_tablename = table_name + '_1'
with open(temp_tablename,'a',encoding='utf8') as f1:
with open(table_name,'r',encoding='utf8') as f:
for line in f:
if not Judegfilter(strlist,line):
f1.write(line)
else:
index += 1
os.remove(table_name)
os.rename(temp_tablename,table_name)
print("Delete %d item data." %index)
def Judegfilter(strlist,line):
flag = False
pos = strlist.index('where')
colNameList = GetTableColName(strlist[pos - 1])
line_list = list(str(line).strip('\n').split(spr))
index = GetIndexInList(colNameList, strlist[pos + 1])
colValue = strlist[pos + 3].strip('"').strip('\'')
if '=' in strlist:
if colValue == line_list[index + 1]:
flag = True
elif 'like' in strlist:
if colValue in line_list[index + 1]:
flag = True
elif colValue.isdigit():
if strlist[pos + 2] == '<':
if int(colValue) > int(line_list[index + 1]):
flag = True
elif strlist[pos + 2] == '>':
if int(colValue) < int(line_list[index + 1]):
flag = True
return flag
def GetTableItemNum(table_name):
index = 0
colName = ''
with open(table_name,'r',encoding='utf8') as f:
for line in f:
if index == 0:
colName = line.strip('\n')
index += 1
if index > 0:
index -= 1
return index,colName
def Update(sqlList,table_name):
'更新数据项'
pass
def Insert(sqlList,table_name):
'插入数据项'
index = sqlList.index('into')
'''
因为sql语句中的方式为table(colname1,cloname2),所以先取相应的值,然后将括号去掉,转换成列表
'''
temp = sqlList[index +1].lower().strip(')')
pos = str(temp).index('(')
insertColName = temp[pos+1:len(temp)].split(',')
if 'phone' not in insertColName:
print('插入唯一键不存在,请检查您的插入语句')
else:
temp = sqlList[index + 2].strip(')')
insertValues = GetValueFromStr(temp)
if len(insertValues) == 0:
print('插入值不能为空,请检查您的sql语句')
else:
InsertDataToDB(table_name, insertColName, insertValues)
def GetValueFromStr(temp):
pos = str(temp).index('(')
insertValues = temp[pos + 1:len(temp)].split(',')
insertValues1 = []
for line in insertValues:
temp1 = line.strip('\'')
insertValues1.append(temp1)
return insertValues1
def InsertDataToDB(table_name, insertColName, insertValues):
'插入数据到文件中'
pos = insertColName.index('phone')
value = insertColName[pos]
flag = False
pos = insertColName.index('phone')
if pos > len(insertValues):
print('插入值过少,请检查您的sql语句')
elif len(insertValues[pos]) == 0:
print('插入值不能为空,请检查您的sql语句')
else:
flag,tableColName = IsValueInDB(insertValues[pos], table_name)
if flag:
print("插入值已存在,请您检查sql语句")
else:
WriteDataToDB(table_name, insertColName, insertValues,tableColName)
def IsValueInDB(value, table_name):
'判断插入值是否已经存在'
index = 0
templist = []
flag = False
with open(table_name,'r',encoding='utf8') as f:
index = 0
for line in f:
if index == 0:
templist = line.lower().strip(spr).split(spr)
elif value in line:
flag = True
break
index += 1
return flag,templist
def WriteDataToDB(table_name, insertColName, insertValues,tableColName):
'将数据组成合理的格式写入到文件中'
indexlist = []
index = GetOrderIndex()
temp = spr + str(index)
# valuedir = GetValue
'''
with open(table_name, 'a',encoding='utf8') as f:
for line in insertColName:
pos = tableColName.index(line)
indexlist.append(pos)
lenNum = len(indexlist)
temp = spr + str(index)
if lenNum == 1:
temp += pos * spr
else:
pos1 = indexlist[lenNum -1] - indexlist[lenNum -2]
temp += pos1 * spr
pos = insertColName.index(line)
temp += insertValues[0]
f.write(temp)
'''
PutOrderIndex(index +1)
print("插入数据成功")
def GetOrderIndex():
'获取自增量最后值,该值存放在文件中'
index = 0
with open('index', 'r', encoding='utf8') as f:
index = int(f.readline())
return index
def PutOrderIndex(orderIndex):
'将自增量写入到文件中做记录'
with open('index', 'w', encoding='utf8') as f:
temp = str(orderIndex)
f.write(temp)
def Condition_query(strlist,table_name):
'条件查询:strlist(将sql语句拆分之后的列表)、strlist(表名)'
colList = list(strlist[1].split(',')) #查询项
pos = GetIndexInList(strlist,'where') #pos 条件判断关键字位置
index = 0
total = -1
with open(table_name, 'r', encoding='utf8') as f:
for line in f: #line文件中读取信息
temp = GetSearchvalue(line,strlist,index,colList,pos)
index += 1
if len(temp) != 0:
print(temp)
total += 1
pass
print('Total:', total)
def GetSearchvalue(line,strlist,index,colList,pos):
'sql语句中的查询条件中,条件项为数字类型'
temp = ''
if index == 0:
temp = Print_colname(strlist, colList,line)
else:
temp = CheckCondition(strlist,line,pos)
pass
return temp
def Print_colname(strlist,colList,line):
temp = ''
line = line.strip('\n')
if '*' in strlist:
temp = line
else:
for colIndex in colList:
temp += colIndex
temp += spr
return temp
def CheckCondition(strlist, line, pos):
'判断当前值是否符合查询条件过滤值'
temp = ''
colNameList = GetTableColName(strlist[pos - 1])
line_list = list(str(line).strip('\n').split(spr))
index = GetIndexInList(colNameList,strlist[pos+1])
colValue = strlist[pos + 3].strip('"').strip('\'')
if '=' in strlist:
if colValue == line_list[index + 1]:
temp = GetDataFromLine(line_list, line, strlist,pos)
elif 'like' in strlist:
if colValue in line_list[index + 1]:
temp = GetDataFromLine(line_list, line, strlist, pos)
elif colValue.isdigit():
if strlist[pos + 2] == '<':
if int(colValue) > int(line_list[index + 1]):
temp = GetDataFromLine(line_list, line, strlist,pos)
elif strlist[pos + 2] == '>':
if int(colValue) < int(line_list[index + 1]):
temp = GetDataFromLine(line_list, line, strlist,pos)
return temp
def GetDataFromLine(line_list, line, strlist,pos):
'将符合条件的数据进行分拣,依据查询的字段名来取相应的值,如果是全字段,则直接返回值'
temp = ''
if '*' in strlist:
temp = line.strip('\n')
else:
selColIndex = list(strlist[1].split(','))
colNameList = GetTableColName(strlist[pos-1])
selColIndexlist = GetIndexWithColName(selColIndex,colNameList)
for data in selColIndexlist:
temp += line_list[data+1].strip('\n')
temp += spr
return temp
def Query(strlist,table_name):
'非条件查询'
index = 0
if '*' in strlist:
with open(table_name, 'r', encoding='utf8') as f:
for line in f:
print(line.strip('\n'))
index += 1
else:
index = Query_someone(strlist,table_name)
print("Total:%d" %(index-1))
def Query_someone(strlist,table_name):
'查询任一一项或者多项数据'
colList = list(strlist[1].split(','))
colnameList = GetTableColName(table_name)
colNameIndex = GetIndexWithColName(colList,colnameList)
'''
1、读取文件中第一行数据,获得字段信息,判断要查询的字段是否为文件字段项,如果不是,
提示查询出错;
2、获取查询字段在文件字段项中的位置。获取该位置,在之后读取文件中的数据时使用到
'''
if len(colNameIndex) == 0:
print('【Error】查询字段不存在')
return 0
else:
colNameIndex.sort()
index = 0
with open(table_name, 'r', encoding='utf8') as f:
for line1 in f:
strInfo = GetColValue(line1, colNameIndex, index)
index += 1
print(strInfo)
return index
def GetTableColName(table_name):
'获取表中字段项列表'
colnameList = []
with open(table_name, 'r', encoding='utf8') as f:
colnameList = list(f.readline().lower().strip('\n').split(spr))
return colnameList
def GetTableName(strSql):
'通过sql语句转化之后的列表,获取到表名'
name = ''
list = strSql.split(' ')
for line in keyword_list:
if line in list:
name_pos = list.index(line)
if len(list) == name_pos+1:
break
elif line == 'into':
temp = list[name_pos+1]
name = SperString(temp,'(')
else:
name = list[name_pos+1]
break
return name
def SperString(strData, sper):
temp = ''
if sper in strData:
pos = strData.index(sper)
temp = strData[0:pos]
else:
temp = strData
return temp
def GetIndexInList(list, name):
'通过列表中的数据项,获取数据项在列表中的位置信息'
if name in list:
return list.index(name)
else:
return -1
def GetIndexWithColName(colList, colnameList = []):
'查询时会遇到查询多项数据,此处是将每个数据项在表中对应的位置信息获取到'
colNameIndex = []
for line in colList:
if line.lower() in colnameList:
index = colnameList.index(line.lower())
colNameIndex.append(index)
return colNameIndex
def GetColValue(colValue,list,index):
'通过表中数据项所在位置,取出相应的值'
strInfo = ''
for line2 in list:
templist = colValue.split(spr)
if index == 0:
strInfo += templist[line2].strip('\n')
else:
strInfo += templist[line2 + 1].strip('\n')
strInfo += spr
return strInfo
def RunSql(strSql):
'执行sql语句'
sqlList = strSql.strip('\n').split(' ')
table_name = GetTableName(strSql)
oper = sqlList[0].lower()
flag,errorInfo = JudgeSqlIsTrue(sqlList,table_name)
if flag:
First_Keyword_list[oper](sqlList,table_name)
else:
print('执行的sql语句有语法错误,错误提示:【%s】。请检查您的执行语句' %errorInfo)
def JudgeSqlIsTrue(strSqlList,table_Name):
'判断执行语句是否符合语法负责'
flag = False
temp = ''
if len(strSqlList) == 0:
print('空语句无法执行')
else:
if strSqlList[0].lower() not in First_Keyword_list:
temp = '执行语句不符合执行规则,没有找到执行关键字'
elif not JudgeTableName(table_Name):
temp = '查询的表不存在'
elif not JudgeColName(strSqlList, table_Name):
temp = '查询的表字段不存在'
else:
flag = True
return flag,temp
def JudgeTableName(table_Name):
isExists = os.path.exists(table_Name)
return isExists
def JudgeColName(strSqlList,table_Name):
'判断操作字段是否在表中'
if 'delete'in strSqlList or '*' in strSqlList:
return True
else:
searchColNamelist = GetSearchNameFromSql(strSqlList)
tablecolNamelist = GetTableColName(table_Name)
if len(searchColNamelist) == 0:
return False
for line in searchColNamelist:
if line not in tablecolNamelist:
return False
return True
def GetSearchNameFromSql(strSqlList):
'从sql语句中提取字段名'
tempList = []
if 'select' in strSqlList:
tempList = strSqlList[1].lower().split(',')
elif 'insert' in strSqlList:
temp = strSqlList[2].lower().strip(')')
if '(' in temp:
pos = temp.index('(')
tempList = (temp[pos+1:len(temp)]).split(',')
print(tempList)
elif 'update' in strSqlList:
pass
return tempList
#strSql = 'select * from staff_table where age > 22'
#select * from staff_table where name like '龙龙'
#insert into staff_table(name,dept) values('龙龙','教师')
import os
time = 0
First_Keyword_list = {'select':SearchAll,'insert':Insert,'update':Update,'delete':Delete}
while time < 3:
strSql = input('sql>')
RunSql(strSql)
time += 1