我最近发现了一些我无法追查的Access SQL查询的错误。我有一个相当简单的SQL查询,用于从旧应用程序中“托管”的访问数据库中检索数据(即数据已经在数据库中,我无法真正控制其中的内容)。
import pyodbc
MDB = '******.MDB'
DRV = '{Microsoft Access Driver (*.mdb)}'
PWD = ''
con = pyodbc.connect('DRIVER={};DBQ={};PWD={}'.format(DRV, MDB, PWD))
sql = ('SELECT Estim.PartNo, Estim.Descrip, Estim.CustCode, Estim.User_Text1, Estim.Revision, ' +
'Estim.Comments, Routing.PartNo AS RPartNo, Routing.StepNo, Routing.WorkCntr, Routing.VendCode, ' +
'Routing.Descrip AS StepDescrip, Routing.SetupTime, Routing.CycleTime, ' +
'Routing.WorkOrVend, ' +
'Materials.PartNo as MatPartNo, Materials.SubPartNo, Materials.Qty, ' +
'Materials.Unit, Materials.TotalQty, Materials.ItemNo, Materials.Vendor ' +
'FROM (( Estim ' +
'INNER JOIN Routing ON Estim.PartNo = Routing.PartNo ) ' +
'INNER JOIN Materials ON Estim.PartNo = Materials.PartNo )')
if 'PartNo' in kwargs:
key = kwargs['PartNo']
sql = sql + 'WHERE Estim.PartNo=?'
cursor = con.cursor().execute(sql, key)
# use this for debuging only
num = 0
for row in cursor.fetchall():
num += 1
return num
这适用于所有PartNo
,除非PartNo
包含小数点。奇怪的是,当PartNo
包含小数点和连字符时,我会得到相应的记录。
kwargs['PartNo'] = "100.100-2" # returns 1 record
kwargs['PartNo'] = "200.100" # returns 0 records
在其他应用程序中查看时,PartNo
都存在,因此我知道应该为两个查询返回记录。
我的第一个想法是确保kwargs['PartNo']
是一个字符串key = str(kwargs['PartNo'])
而没有任何变化。
我还尝试在'PartNo'
值附近放置引号但没有成功。 key = '\'' + kwargs['PartNo'] + '\''
最后,我试图逃避.
但没有成功(我意识到这会破坏大多数查询,但我只是试图用一段时间来追踪问题)key = str(kwargs['partNo']).replace('.', '"."')
我知道使用查询参数应该为我处理所有的转义,但在这一点上,我只是想弄清楚发生了什么。有什么想法吗?
答案 0 :(得分:2)
所以问题不在于查询参数 - 一切都按预期工作。问题出在SQL语句中。我错误地假设 - 并且从未检查过 - Materials
表中有与PartNo
匹配的记录。
INNER JOIN Materials ON Estim.PartNo = Materials.PartNo
如果在两个表中都找到PartNo
,将仅返回记录,在这种情况下,它不是。
将其更改为
LEFT OUTER JOIN Materials ON Estim.PartNo = Materials.PartNo
产生预期结果。有关JOINS的信息,请参阅此处。 https://msdn.microsoft.com/en-us/library/bb243855(v=office.12).aspx
至于print (repr(key))
- flask正确处理上游的kwarg类型
api.add_resource(PartAPI, '/api/v1.0/part/<string:PartNo>'
所以当我在浏览器中运行它时,我得到了“全长”字符串。当使用python -c .......
在cmd行中运行时,我没有像Gord指出的那样正确处理参数类型,因此它截断了尾随的零。我不认为烧瓶部分是相关的,所以我从未在原始问题中添加它。