sqlite / python - 没有封闭引号的命名参数?

时间:2010-11-16 05:24:37

标签: python sqlite prepared-statement named-parameters

在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 .

有没有办法提示execute方法解释所提供的参数,使它不包含引号?

我已经写了一个小测试程序来完全探索这个,所以它的价值在于:

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()

有兴趣听说操作执行方法以使其工作。

2 个答案:

答案 0 :(得分:3)

SELECT DISTINCT(C1) FROM T1 C1不是字符串值,它是一段SQL代码。参数(在execute中转义)用于插入值,而不是代码片段。

答案 1 :(得分:0)

您正在使用绑定,绑定只能用于值,而不能用于表名或列名。您将不得不使用字符串插值/ formstting来获得所需的效果,但如果列名来自不受信任的来源,它会让您对SQL注入攻击持开放态度。在这种情况下,您可以清理字符串(例如,只允许使用字母数字)并使用授权程序界面检查不会发生意外活动。