无法使用 pypyodbc 在 python 中使用 where 子句运行 mssql 选择查询
Posted
技术标签:
【中文标题】无法使用 pypyodbc 在 python 中使用 where 子句运行 mssql 选择查询【英文标题】:Cannot run mssql select query with where clause within python using pypyodbc 【发布时间】:2017-03-30 13:52:52 【问题描述】:我正在使用库 pypyodbc
并尝试使用 where
子句在 mssql 中运行 select
查询。
但是我得到的错误表明语法错误。
Error here ('42000', "[42000] [FreeTDS][SQL Server]Incorrect syntax near the keyword 'User'.")
我的函数中的查询如下;
try:
selectUserDetails = "SELECT Username,Password FROM User WHERE Username = ?"
cursor.execute(selectUserDetails,(username,))
for row in cursor:
print(row);
except Exception as e:
print('Error here ' + str(e))
我获取光标的函数如下;
def msDbCred():
try:
from msDb import connection_string
conn = pypyodbc.connect(connection_string)
cursor = conn.cursor();
return cursor;
except pymysql.err.OperationalError:
sys.exit("Invalid Input: Wrong username/db or password found, please try again")
cursor = msDbCred()
我的数据库凭据存储在名为 msDb.py 的不同文件中
db_host = '127.0.0.1'
db_name = 'TD_1.0'
db_user = 'ReadOnly'
db_password = 'mypaswword'
connection_string = 'Driver=SQL Server;Server=' + db_host + ';Database=' + db_name + ';uid=' + db_user + ';PWD=' + db_password + ';'
我的问题是,查询本身是否有问题。因为我在代码中其他地方的另一个查询中使用了相同的格式,所以它可以工作。还是我的功能有什么问题?
更新:
@Gord Thompson 说我应该更改我的查询。
我已经改了,我的查询改为;
selectUserDetails = "SELECT Username FROM [TD_1.0].[dbo].[User] WHERE Username = ?"
cursor.execute(selectUserDetails,(username,))
但是现在我得到了错误;
('HY010', '[HY010] [unixODBC][Driver Manager]Function sequence error')
【问题讨论】:
尝试将表名括在方括号中:[User]
@GordThompson 我根据您的评论更改了我的查询,但现在得到一个不同的错误。如上图所示更新
USER
是一个关键字。你必须把它包装起来,例如[User]
。您不必使用由三部分组成的名称。除此之外,您的查询使用 ?
,这不是在 SQL Server 中使用参数的方式。 FreeTDS 无论如何都不支持参数,充其量它执行替换。进一步的问题 - 您加载用户密码而不是存储和比较哈希?这几乎是在乞求像新闻中那样的黑客攻击。
你为什么使用 FreeTDS?为什么不直接使用 ODBC?至于检查密码,正确的做法是使用至少 1000 次迭代的强加密散列算法从密码和盐值生成和存储散列。每当用户尝试登录时,再次生成哈希并将其与存储的哈希进行比较。
使用 pymssql 或 pyodbc 检查 Microsoft 在 connecting to SQL Server from Python 上的文档。查看How do I use SQL parameters with python? 了解如何在 pymssql 中使用真正的参数化查询
【参考方案1】:
我设法找出错误在哪里以及如何解决它。
在我的 msDbCred() 函数中,我直接返回光标。我正在另一个文件中进行测试,并认为这是问题所在。
所以我创建了一个空数组并将光标附加到数组中,然后返回数组。
然后在我的代码的其他地方使用数组的第一个索引作为光标
def msDbCred():
cred = []
try:
from msDb import connection_string
conn = pypyodbc.connect(connection_string)
cursor = conn.cursor();
cred.append(cursor)
return cred
except pymysql.err.OperationalError:
sys.exit("Invalid Input: Wrong username/db or password found, please try again")
cursor = msDbCred()
然后使用游标数组的第一个索引
try:
selectUserDetails = "SELECT Username,Password,UserId FROM [User] WHERE Username = '"+str(username)+"' AND IsEditor = '"+str(True)+"'"
cursor[0].execute(selectUserDetails)
for row in cursor[0]:
return row[0] == username and row[1] == password
except Exception as e:
print('Error is ' + str(e))
现在可以了。
【讨论】:
以上是关于无法使用 pypyodbc 在 python 中使用 where 子句运行 mssql 选择查询的主要内容,如果未能解决你的问题,请参考以下文章
怎样在Anaconda中的某一个环境中安装Python的相关包(pypyodbc)
如何在 Python 上使用 Windows Auth 登录 MSSQL?