2010-10-30 63 views
0

我对使用SQL查询很新。任何建议,以改善这一点的代码: (顺便说一下,我真的不在乎这里的sql安全;这是一个代码,将在一个pyexe文件连接到本地sqlite文件 - 所以它不会感觉担心查询的安全性)。任何改善此功能的建议?

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) 
+2

不要习惯坏习惯。始终关心安全。 – 2010-10-30 16:18:23

+0

考虑到sqlite3是Python标准库的一部分,您将不得不为更好的理由不使用它的参数化查询。 – 2010-10-30 17:52:26

+0

建议是*不*要在同一行放置多个语句。这包括'如果'及其分支。 – Amnon 2010-10-30 19:52:46

回答

2

如果这是一个一次性的脚本,你完全信任所有的输入数据,你只需要完成一项工作,那就好了。

如果这是一个系统的一部分,这是指示那种在它的代码,有几个问题:

  1. 不要通过追加字符串构造SQL查询。你说你不关心安全性,但是这是一个很大的问题,很容易解决,那么真的 - 你应该一直这样做

  2. 这个函数似乎使用和操纵全局状态。再说一遍,如果这是一个小的一次性使用脚本,那就去做吧 - 在跨越几个文件的系统中,这变得无法维护。

  3. 命名约定---不是按照市值的事情

  4. 名称的任何一致性是没有帮助的。 QA,D,QB,QA和QB似乎不是同一种东西 - 一个是领域,另一个是价值。

  5. 各种有问题的东西都没有注释 - 为什么最大.0001? GHolder到底是什么?这个循环最终会做什么?实际上,代码应该更清楚,但如果没有,则将维护者抛诸脑后。

+0

+1,但我不同意第一段。没有理由不遵循这些小脚本中的规则,他不应该建立坏习惯。而且,即使他现在不知道,他也许会在将来重用该脚本。 – Amnon 2010-10-30 16:39:45

0

您应该检查SQL注入。确保QA中没有SQL语句。如果适用,你也应该添加斜杠。

0
  1. 使用

    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'" 
  1. 关心安全性(SQL注入)。
  2. 看看任何ORM(例如SqlAlchemy)。它使事情变得简单:)
+2

这不会阻止SQL注入。将QB设置为带有单引号的内容,并且不会被转义。为防止SQL注入,请勿从变量创建字符串 - 使用数据库层将对象作为参数传入。 – 2010-10-30 16:36:56

1
  • 使用更具描述性的变量名比QAQB

  • 注释代码。

  • 不要把多个语句在同一行

  • 尽量不要使用全局变量。改用成员变量。

  • 如果QA和QB可以来自用户的输入,不要用它们来构建SQL查询