Python pyodbc如何向execute语句插入变量?
我正在使用Python3.3、PyODBC 1.2.1和Quickbooks Enterprise 12公司文件,这些文件都是通过FlexDBC版本14访问的。我不熟悉编程和python,因此仍在学习:我可以使用PyODBC示例运行查询,并生成预期结果 请注意execute中的硬编码电子邮件地址。这与预期的效果一样:Python pyodbc如何向execute语句插入变量?,python,odbc,quickbooks,pypyodbc,Python,Odbc,Quickbooks,Pypyodbc,我正在使用Python3.3、PyODBC 1.2.1和Quickbooks Enterprise 12公司文件,这些文件都是通过FlexDBC版本14访问的。我不熟悉编程和python,因此仍在学习:我可以使用PyODBC示例运行查询,并生成预期结果 请注意execute中的硬编码电子邮件地址。这与预期的效果一样: def get_customer_id(search_col,search_str): '''(str,str) --> str >>>g
def get_customer_id(search_col,search_str):
'''(str,str) --> str
>>>get_customer_id(email, foo@foo.com)
80000001-1385782702
'''
cur.execute("SELECT listid FROM CUSTOMER WHERE email='foo@foo.com'")
for row in cur.fetchall():
for field in row:
return field
如果我尝试使用从PyODBC文档中读取的参数执行相同的操作,我会抛出一个错误。我觉得引号和参数标记有问题
def get_customer_id(search_col,search_str):
'''(str,str) --> str
>>>get_customer_id(email, foo@foo.com)
80000001-1385782702
'''
cur.execute("SELECT listid FROM CUSTOMER WHERE email=?",(search_str,))
for row in cur.fetchall():
for field in row:
return field
想变得更像蟒蛇?我真的想重用这个函数来搜索不同的列。比如:
cur.execute("SELECT listid FROM CUSTOMER WHERE search_str=search_col")
我已经查看了其他几个线程,其中大多数似乎只是处理参数,而不是要搜索的列。有人能帮我学这个吗
PS忘记包含回溯:
Traceback (most recent call last):
File "C:\Users\Mike\Documents\Projects\qb_sync\quickbooks.py", line 32, in <module>
print(get_customer_id('email','foo@foo.com'))
File "C:\Users\Mike\Documents\Projects\qb_sync\quickbooks.py", line 27, in get_customer_id
cur.execute("SELECT listid FROM CUSTOMER WHERE email=?",[search_str,])
File "C:\Python\lib\site-packages\pypyodbc.py", line 1457, in execute
self._BindParams(param_types)
File "C:\Python\lib\site-packages\pypyodbc.py", line 1420, in _BindParams
check_success(self, ret)
File "C:\Python\lib\site-packages\pypyodbc.py", line 982, in check_success
ctrl_err(SQL_HANDLE_STMT, ODBC_obj.stmt_h, ret, ODBC_obj.ansi)
File "C:\Python\lib\site-packages\pypyodbc.py", line 960, in ctrl_err
raise Error(state,err_text)
pypyodbc.Error: ('HY004', '[HY004] [Microsoft][ODBC Driver Manager] SQL data type out of range')
[Finished in 1.7s]
到目前为止,我得到了一半的答案。如果我在调用函数之前格式化字符串,这对一个参数有效
print(get_custid_email(b'foo@foo.org'))
cur.execute("""SELECT listid FROM CUSTOMER WHERE email=?""",[email])
不过,我仍然无法让它对列名执行相同的操作
print(get_custid_email(b'email',b'foo@foo.org'))
cur.execute("""SELECT listid FROM CUSTOMER WHERE ?=?""",[column, email])
这会引发不同的错误:
Traceback (most recent call last):
File "C:\Users\Mike\Documents\Projects\qb_sync\quickbooks.py", line 34, in <module>
print(get_custid_email(b'wendy.lindsay@gmail.com'))
File "C:\Users\Mike\Documents\Projects\qb_sync\quickbooks.py", line 29, in get_custid_email
cur.execute("""SELECT listid FROM CUSTOMER WHERE ?=?""",['email',email])
pyodbc.ProgrammingError: ('42S00', '[42S00] [QODBC] Data type of parameter cannot be determined (11023) (SQLPrepare)')
到目前为止,我得到了一半的答案。如果我在调用函数之前格式化字符串,这对一个参数有效
print(get_custid_email(b'foo@foo.org'))
cur.execute("""SELECT listid FROM CUSTOMER WHERE email=?""",[email])
不过,我仍然无法让它对列名执行相同的操作
print(get_custid_email(b'email',b'foo@foo.org'))
cur.execute("""SELECT listid FROM CUSTOMER WHERE ?=?""",[column, email])
这会引发不同的错误:
Traceback (most recent call last):
File "C:\Users\Mike\Documents\Projects\qb_sync\quickbooks.py", line 34, in <module>
print(get_custid_email(b'wendy.lindsay@gmail.com'))
File "C:\Users\Mike\Documents\Projects\qb_sync\quickbooks.py", line 29, in get_custid_email
cur.execute("""SELECT listid FROM CUSTOMER WHERE ?=?""",['email',email])
pyodbc.ProgrammingError: ('42S00', '[42S00] [QODBC] Data type of parameter cannot be determined (11023) (SQLPrepare)')
我认为
cur.executeSELECT listid FROM CUSTOMER WHERE?=?,[列,电子邮件]
不能被数据库引擎而不是PyODBC或任何其他odbc接口接受。数据库引擎拒绝接受查询以在列名上使用参数
您可能需要尝试以下方法来重用该函数:
# First construct your dynamic query for the targeted column
sql = """SELECT listid FROM CUSTOMER WHERE %s=?""" %(column)
# Then provide the dynamic value for the dynamic query string
cur.execute(sql, (value,))
我认为
cur.executeSELECT listid FROM CUSTOMER WHERE?=?,[列,电子邮件]
不能被数据库引擎而不是PyODBC或任何其他odbc接口接受。数据库引擎拒绝接受查询以在列名上使用参数
您可能需要尝试以下方法来重用该函数:
# First construct your dynamic query for the targeted column
sql = """SELECT listid FROM CUSTOMER WHERE %s=?""" %(column)
# Then provide the dynamic value for the dynamic query string
cur.execute(sql, (value,))
Python3还有str.format方法,它将对字符串中的{index}项进行字符串替换。如果您有许多值要注入字符串,如: myStr=我喜欢{0}和{1},但我不喜欢{2}苹果、香蕉、菠菜 迈斯特 我喜欢苹果和香蕉,但我不喜欢菠菜 值得注意的是,这种替换字符串查询中的值的方法可能会受到sql注入的影响。
更安全的方法是使用参数化的存储过程。Python3还有str.format方法,它将对字符串中的{index}项进行字符串替换。如果您有许多值要注入字符串,如: myStr=我喜欢{0}和{1},但我不喜欢{2}苹果、香蕉、菠菜 迈斯特 我喜欢苹果和香蕉,但我不喜欢菠菜 值得注意的是,这种替换字符串查询中的值的方法可能会受到sql注入的影响。
更安全的方法是使用参数化存储过程。我也用pyodbc检查过,它会产生相同的错误。我也用pyodbc检查过,它会产生同样的错误。我认为您必须使用b而不是查询,因为数据库中定义的字符串列是非Unicode字符串,例如varchar而不是Unicode类型,例如nvarcharI认为您必须使用b而不是查询,因为数据库中定义的字符串列是非Unicode字符串,例如varchar而不是Unicode类型,例如nvarchar