sqlite / python - 命名参数不带引号?
在 SQLite 中使用带有命名参数的准备好的语句时(特别是使用 python sqlite3 模块 http://docs.python .org/library/sqlite3.html)是否可以包含字符串值而不用引号括起来?
我得到了这个:
columnName = '''C1'''
cur = cur.execute('''SELECT DISTINCT(:colName) FROM T1''', {'colName': columnName})
看来我最终得到的 SQL 是这样的:
SELECT DISTINCT('C1') FROM T1
当然这没有多大用处,我真正想要的是:
SELECT DISTINCT(C1) FROM T1 .
有什么方法可以提示执行方法来解释这样的提供的参数这样它就不会在它们周围加上引号?
我编写了一个小测试程序来充分探索这一点,因此它的价值在于:
import sys
import sqlite3
def getDatabaseConnection():
DEFAULTDBPATH = ':memory:'
conn = sqlite3.connect(DEFAULTDBPATH, detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
conn.text_factory = str
return conn
def initializeDBTables(conn):
conn.execute('''
CREATE TABLE T1(
id INTEGER PRIMARY KEY AUTOINCREMENT,
C1 STRING);''')
cur = conn.cursor()
cur.row_factory = sqlite3.Row # fields by name
for v in ['A','A','A','B','B','C']:
cur.execute('''INSERT INTO T1 values (NULL, ?)''', v)
columnName = '''C1'''
cur = cur.execute('''SELECT DISTINCT(:colName) FROM T1''', {'colName': columnName})
#Should end up with three output rows, in
#fact we end up with one
for row in cur:
print row
def main():
conn = getDatabaseConnection()
initializeDBTables(conn)
if __name__ == '__main__':
main()
有兴趣了解如何操纵执行方法以使其发挥作用。
When using prepared statements with named parameters in SQLite (specifically with the python sqlite3 module http://docs.python.org/library/sqlite3.html ) is there anyway to include string values without getting quotes put around them ?
I've got this :
columnName = '''C1'''
cur = cur.execute('''SELECT DISTINCT(:colName) FROM T1''', {'colName': columnName})
And it seems the SQL I end up with is this :
SELECT DISTINCT('C1') FROM T1
which isn't much use of course, what I really want is :
SELECT DISTINCT(C1) FROM T1 .
Is there any way to prompt the execute method to interpret the supplied arguments in such a way that it doesn't wrap quotes around them ?
I've written a little test program to explore this fully so for what it's worth here it is :
import sys
import sqlite3
def getDatabaseConnection():
DEFAULTDBPATH = ':memory:'
conn = sqlite3.connect(DEFAULTDBPATH, detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
conn.text_factory = str
return conn
def initializeDBTables(conn):
conn.execute('''
CREATE TABLE T1(
id INTEGER PRIMARY KEY AUTOINCREMENT,
C1 STRING);''')
cur = conn.cursor()
cur.row_factory = sqlite3.Row # fields by name
for v in ['A','A','A','B','B','C']:
cur.execute('''INSERT INTO T1 values (NULL, ?)''', v)
columnName = '''C1'''
cur = cur.execute('''SELECT DISTINCT(:colName) FROM T1''', {'colName': columnName})
#Should end up with three output rows, in
#fact we end up with one
for row in cur:
print row
def main():
conn = getDatabaseConnection()
initializeDBTables(conn)
if __name__ == '__main__':
main()
Would be interested to hear of anyway of manipulating the execute method to allow this to work.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在 SELECT DISTINCT(C1) FROM T1 中,
C1
不是字符串值,而是一段 SQL 代码。参数(在execute
中转义)用于插入值,而不是代码片段。In
SELECT DISTINCT(C1) FROM T1
theC1
is not a string value, it is a piece of SQL code. The parameters (escaped inexecute
) are used to insert values, not pieces of code.您正在使用绑定,并且绑定只能用于值,不能用于表或列名称。您必须使用字符串插值/格式设置来获得您想要的效果,但如果列名来自不受信任的来源,它确实会让您面临 SQL 注入攻击。在这种情况下,您可以清理字符串(例如仅允许字母数字)并使用授权者界面来检查不会发生意外活动。
You are using bindings and bindings can only be used for values, not for table or column names. You will have to use string interpolation/formstting to get the effect you want but it does leave you open to SQL injection attacks if the column name came from an untrusted source. In that case you can sanitize the string (eg only allow alphanumerics) and use the authorizer interface to check no unexpected activity will happen.