Python 如何在参数和值都是变量的情况下进行SQLite查询?
我试图让用户搜索一个SQL表,方法是首先输入要搜索的参数,然后输入要在该参数内搜索的值Python 如何在参数和值都是变量的情况下进行SQLite查询?,python,sql,sqlite,Python,Sql,Sqlite,我试图让用户搜索一个SQL表,方法是首先输入要搜索的参数,然后输入要在该参数内搜索的值 import sqlite3 conn = sqlite3.connect('[project directory]/db.sqlite3') c = conn.cursor() def search_entry(): '''Searches database based on user input, returns rows ''' # Search parameters di
import sqlite3
conn = sqlite3.connect('[project directory]/db.sqlite3')
c = conn.cursor()
def search_entry():
'''Searches database based on user input, returns rows
'''
# Search parameters dictionary
search_par = {
'1': 'id',
'2': 'date',
'3': 'account',
'4': 'trans_type',
'5': 'main_cat',
'6': 'sub_cat',
'7': 'name',
'8': 'amount',
'9': 'all',
}
print('\n')
for key in search_par:
print(key, ': ', search_par[key])
print('\n')
# Select parameter number to search by
while True:
try:
par_select = str(int(input('Select parameter number to search by: ')))
if (int(par_select) < 10 and int(par_select) > 0):
break
else:
pass
except:
pass
sel_par = search_par[par_select] # Select corresponding parameter
# Select value to search
while True:
try:
id_search = input('Select value to search: ')
break
except:
pass
c.execute('SELECT * FROM form_entry WHERE (?)=(?)', (sel_par, id_search,))
rows = c.fetchall()
for row in rows:
for col in row:
print('%s,' % col)
print('\n')
search_entry()
我获取这两个输入,将它们分配给两个不同的变量,然后将这些变量传递到SQLExecute命令中。如果我只传递value变量并对参数进行硬编码,而不是相反的方式,那么这是可行的。这表明问题在于处理参数变量,但我不知道问题是什么
这将是一个Django站点,但目前我只是将其作为一个命令行应用程序进行测试。它运行的是Python 3.6.8和sqlite3
我试着只对参数进行硬编码并动态输入值,这是有效的,反之亦然,这是无效的。我还尝试使用不同的值,这些值包含不同的值类型int、varchar等,以确保传递给execute命令的变量类型没有问题,并且它们在硬编码参数时都起作用
import sqlite3
conn = sqlite3.connect('[project directory]/db.sqlite3')
c = conn.cursor()
def search_entry():
'''Searches database based on user input, returns rows
'''
# Search parameters dictionary
search_par = {
'1': 'id',
'2': 'date',
'3': 'account',
'4': 'trans_type',
'5': 'main_cat',
'6': 'sub_cat',
'7': 'name',
'8': 'amount',
'9': 'all',
}
print('\n')
for key in search_par:
print(key, ': ', search_par[key])
print('\n')
# Select parameter number to search by
while True:
try:
par_select = str(int(input('Select parameter number to search by: ')))
if (int(par_select) < 10 and int(par_select) > 0):
break
else:
pass
except:
pass
sel_par = search_par[par_select] # Select corresponding parameter
# Select value to search
while True:
try:
id_search = input('Select value to search: ')
break
except:
pass
c.execute('SELECT * FROM form_entry WHERE (?)=(?)', (sel_par, id_search,))
rows = c.fetchall()
for row in rows:
for col in row:
print('%s,' % col)
print('\n')
search_entry()
这向我表明,问题不在于变量本身,而在于在SQL查询中将变量作为参数传递。我试着查找有类似问题的人,但我不仅没有找到任何,而且也没有找到任何官方文档或其他表明可以或希望将变量作为参数传递的文档
import sqlite3
conn = sqlite3.connect('[project directory]/db.sqlite3')
c = conn.cursor()
def search_entry():
'''Searches database based on user input, returns rows
'''
# Search parameters dictionary
search_par = {
'1': 'id',
'2': 'date',
'3': 'account',
'4': 'trans_type',
'5': 'main_cat',
'6': 'sub_cat',
'7': 'name',
'8': 'amount',
'9': 'all',
}
print('\n')
for key in search_par:
print(key, ': ', search_par[key])
print('\n')
# Select parameter number to search by
while True:
try:
par_select = str(int(input('Select parameter number to search by: ')))
if (int(par_select) < 10 and int(par_select) > 0):
break
else:
pass
except:
pass
sel_par = search_par[par_select] # Select corresponding parameter
# Select value to search
while True:
try:
id_search = input('Select value to search: ')
break
except:
pass
c.execute('SELECT * FROM form_entry WHERE (?)=(?)', (sel_par, id_search,))
rows = c.fetchall()
for row in rows:
for col in row:
print('%s,' % col)
print('\n')
search_entry()
我希望这会返回查询结果,例如,如果用户选择按id搜索,然后搜索id 19,我希望这两个变量被传递到execute命令,并执行搜索。相反,我没有得到任何回报。没有错误,只是没有输出。用两个字来说:你不能
SQL只接受值的参数化,而不接受标识符、列名、表名等。why是一个较长的对话,但它类似于为什么在编程语言中不能让变量的名称来自另一个变量
你唯一能做的就是用你的编程语言构建你的sql;串联列名并将参数值附加到命令对象使用的集合
这是一个伪代码,我不写python,抱歉:
c.execute('SELECT * FROM form_entry WHERE '+colnamesarray[i]=?', colvaluesarray[i])
您也可以尝试使用以下格式
c.execute("SELECT * FROM form_entry WHERE {}" .format(Variable))
我不能代表SQLite,但一般来说,除非使用动态SQL,否则不能将表名或列名作为参数传递。在SQLite中搜索如何使用动态SQL,这可能会有所帮助。当前端编程语言可以动态创建SQL时,使用动态SQL并没有多大意义——可能是一种令人困惑的间接寻址,使用python生成运行查询的动态SQL;我只是让python生成queryAh,这就解释了。非常感谢。你知道这样做是否安全和/或希望按照你的建议去做吗?@Nicolas如果是用户输入,那肯定是不安全的。但是如果你能100%确保列名是有效的,那就不会有问题;连接列名是安全的,因为作为开发人员,您知道列名,并且不会在其中添加黑客。不允许用户指定列名。用户只提供输入值,但这是不可破解的,因为您将该值放入了参数中。只要将参数占位符串联在一起,然后将值放入参数中,就可以通过字符串concat构建sql