我是处理SQL查询的新手。任何改进这段代码的建议: (顺便说一下,我真的不关心这里的sql安全性;这是一些代码,它将在连接到本地sqlite文件的pyexe文件中 - 所以在这里担心查询的安全性是没有意义的)
def InitBars(QA = "GDP1POP1_20091224_gdp", QB = "1 pork", reset = False):
global heights, values
D, heights, values, max, = [], {}, {}, 0.0001
if reset: GHolder.remove()
Q = "SELECT wbcode, Year, "+QA+" FROM DB WHERE commodity='"+QB+"' and "+QA+" IS NOT 'NULL'"
for i in cursor.execute(Q):
D.append((str(i[0]) + str(i[1]), float(i[2])))
if float(i[2]) > max: max = float(i[2])
for (i, n) in D: heights[i] = 5.0 / max * n; values[i] = n
Gui["YRBox_Slider"].set(0.0)
Gui["YRBox_Speed"].set(0.0)
遵循建议后,这就是我得到的:
def InitBars(QA = "GDP1POP1_20091224_gdp", QB = "1 pork", reset = False):
global heights, values; D, heights, values, max, = [], {}, {}, 0.0001
if reset: GHolder.remove()
Q = "SELECT wbcode||Year, %s FROM DB WHERE commodity='%s' and %s IS NOT 'NULL'" % (QA, QB, QA)
for a, b in cursor.execute(Q):
if float(b) > max: max = float(b)
values[a] = float(b)
for i in values: heights[i] = 5.0 / max * values[i]
Gui["YRBox_Slider"].set(0.0); Gui["YRBox_Speed"].set(0.0)
答案 0 :(得分:2)
如果这是一个一次性的脚本,你完全信任所有的输入数据而你只需要完成一份工作,那就好了。
如果这是系统的一部分,并且这表明其中的代码类型,则存在以下几个问题:
不要通过附加字符串来构造SQL查询。你说你不关心安全问题,但这是一个很大的问题,很容易解决,然后真的 - 你应该一直这样做
此函数似乎使用和操纵全局状态。同样,如果这是一个小的一次性使用脚本,那就去吧 - 在只包含几个文件的系统中,这就无法维护。
命名约定 - 不遵循大写的任何一致性
事物的名称根本没用。 QA,D,QB, - QA和QB似乎都不是同一类 - 一个是字段,另一个是值。
各种可疑的东西都没有注释 - 为什么max .0001?什么是GHolder?那个循环最后会做什么?实际上,代码应该更清晰,但如果没有,请给维护者一个骨头。
答案 1 :(得分:1)
使用比QA
和QB
更具描述性的变量名。
评论代码。
不要在同一行中放置多个语句
尽量不要使用全局变量。改为使用成员变量。
如果QA和QB可能来自用户输入,请不要使用它们来构建SQL查询
答案 2 :(得分:0)
您应该检查SQL注入。确保QA中没有SQL语句。如果适用,你也应该添加斜杠。
答案 3 :(得分:0)
使用
Q = "SELECT wbcode, Year, %s FROM DB WHERE commodity='%s' and %s IS NOT 'NULL'" % (QA, QB, QA)
代替:
Q = "SELECT wbcode, Year, "+QA+" FROM DB WHERE commodity='"+QB+"' and "+QA+" IS NOT 'NULL'"