[英]query of sqlite3 with python using '?'
我有一个包含三列id,word,essay
。我想使用( ?
)进行查询。 sql语句为sql1 = "select id,? from training_data"
。 我的代码如下:
def dbConnect(db_name,sql,flag):
conn = sqlite3.connect(db_name)
cursor = conn.cursor()
if (flag == "danci"):
itm = 'word'
elif flag == "wenzhang":
itm = 'essay'
n = cursor.execute(sql,(itm,))
res1 = cursor.fetchall()
return res1
但是,当我print dbConnect("data.db",sql1,"danci")
,获得的结果是[(1,'word'),(2,'word'),(3,'word')...].
我真正想要得到的是[(1,'the content of word column'),(2,'the content of word column')...]
。 我该怎么办 ? 请给我一些想法。
您不能将占位符用于标识符-只能用于文字值。
我不知道在这种情况下的建议,因为您的函数需要一个数据库nasme,一个SQL字符串和一个标记来说明如何修改该字符串。 我认为最好只通过前两个,写类似
sql = {
"danci": "SELECT id, word FROM training_data",
"wenzhang": "SELECT id, essay FROM training_data",
}
然后用以下任一方法调用它
dbConnect("data.db", sql['danci'])
要么
dbConnect("data.db", sql['wenzhang'])
但是,很大程度上取决于您为何要dbConnect
根据从外部传入的字符串来决定要提取的列。 这是一个不寻常的设计。
更新-SQL注入
有关SQL注入和污染 数据的问题已得到充分证明,但这是一个摘要。
原理是,从理论上讲,只要所有数据源都在他的控制之下,程序员就可以编写安全的程序。 一旦他们在不检查程序完整性的情况下使用程序外部的任何信息,安全性就会受到威胁。
这些信息的范围很广,从显而易见的命令行参数传递到模糊的环境变量(如果PATH
环境变量是可修改的),那么有人可能会诱使程序执行与目标文件完全不同的文件。
Perl通过Taint Checking提供了直接的帮助来避免这种情况,但是SQL Injection是与之相关的门户。
假设您从未经验证的外部来源获取数据库列的值,并且该值在您的程序中显示为$val
。 然后,如果你写
my $sql = "INSERT INTO logs (date) VALUES ('$val')";
$dbh->do($sql);
那么看起来就可以了。 例如,如果$val
设置为2014-10-27
则$sql
变为
INSERT INTO logs (date) VALUES ('2014-10-27')
一切都很好。 但是,现在假设我们的数据是由不小心或彻头彻尾的恶意软件提供的,并且您的$val
来自其他地方,
2014-10-27'); DROP TABLE logs; SELECT COUNT(*) FROM security WHERE name != '
现在看起来不太好。 $sql
设置为此(添加了换行符)
INSERT INTO logs (date) VALUES ('2014-10-27');
DROP TABLE logs;
SELECT COUNT(*) FROM security WHERE name != '')
它像以前一样在logs
表中添加一个条目,结束然后继续操作,删除整个logs
表并计算security
表中的记录数。 那根本不是我们要记住的,我们必须谨防。
立即的解决方案是使用占位符 ?
在准备好的语句中,然后在调用execute
传递实际值。 这不仅可以加快处理速度,因为SQL语句仅可以准备(编译)一次,而且可以通过为数据类型适当地引用每个提供的值并转义任何嵌入式引号来保护数据库免受恶意数据的侵害 ,从而无法关闭一个声明,另一个打开另一个。
整个概念在Randall Munroe出色的XKCD漫画中得到了幽默
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.