【问题标题】:pyodbc with MS Access expecting too many parameters带有 MS Access 的 pyodbc 需要太多参数
【发布时间】:2017-05-13 17:00:11
【问题描述】:

我正在尝试在某个时间范围内查询 Access DB 以获取结果。当我查询时,我想自动在输出中添加一列,指定数据属于哪一周(从几周的范围内)。通过将参数传递给 select 语句来生成自动列。我一直在两个错误之间来回走动,我不知道为什么。

错误 1) 参数太少。

错误 2) JOIN 中的语法错误

我的python代码:

错误 1 ​​代码:

qry = '''
    SELECT [PreQuery].[defect], SUM([PreQuery].[qty_rej] + [PreQuery].[qty_rew]) AS [qty_defect], ? AS [wk_no]
    FROM (
        SELECT [Sort].[Date of Sort] AS [srt_date], [Part].[Part Name] AS [prt_no], [Defect Table].[Defect2] AS [defect], [Defect Table].[Quantity Rejected] AS [qty_rej], [Defect Table].[Quantity Reworked] AS [qty_rew]
        FROM (([Defect Table] LEFT JOIN [Sort] ON [Defect Table].[Sort Number] = [Sort].[Sort Number]) LEFT JOIN [Part] ON [Sort].[Part Number] = [Part].[Part Number])) AS PreQuery LEFT JOIN [Defects] ON [Defects].[Defect Code] = [PreQuery].[Defect2]
    WHERE (([Sort].[Date of Sort] BETWEEN ? AND ?) AND ([Part].[Part Name] LIKE ? & '_TZ______'))
    GROUP BY [defect], [wk_no];'''

引发以下错误:

pyodbc.Error: ('07002', '[07002] [Microsoft][ODBC Microsoft Access Driver] Too few parameters. Expected 8. (-3010) (SQLExecDirectW)')

从 [Sort].[Date of Sort] 和 [Part].[Part Name] 中删除别名会重现相同的错误,只是驱动程序需要 6 参数而不是 8 和以前一样。在任何一种情况下,整个语句中只有四个 ?,因此数据库应该期待 4 个参数。

错误 2 代码:

qry = '''
    SELECT ? AS [wk_no], [defect], SUM([qty_rej] + [qty_rew]) AS [qty_defect]
    FROM (
        SELECT [Sort].[Date of Sort], [Part].[Part Name], [Defect Table].[Defect2] AS [defect], [Defect Table].[Quantity Rejected] AS [qty_rej], [Defect Table].[Quantity Reworked] AS [qty_rew]
        FROM (([Defect Table] LEFT JOIN [Sort] ON [Defect Table].[Sort Number] = [Sort].[Sort Number])
        LEFT JOIN [Part] ON [Sort].[Part Number] = [Part].[Part Number]))
    LEFT JOIN [Defects] ON [Defects].[Defect Code] = [Defect Table].[Defect2]
    WHERE (([Sort].[Date of Sort] BETWEEN ? AND ?) AND ([Part].[Part Name] LIKE ? & '_TZ______'))
    GROUP BY [defect], [wk_no];'''

这引发了:

pyodbc.ProgrammingError: ('42000', '[42000] [Microsoft][ODBC Microsoft Access Driver] Syntax error in JOIN operation. (-3510) (SQLExecDirectW)')

我自己检查了内部 select 语句,它在任何一种情况下都执行得非常好。此外,我看不到任何明显的语法错误(PyCharm 也无法检查 MySQL 方言)。

【问题讨论】:

  • 第二个错误,我认为子查询需要一个别名。
  • 另外,你不应该需要所有这些方括号。仅当列名包含空格时,Access 才需要它们。如果 Access DB 中不存在任何列,则方括号中的项目将被视为参数。因此,如果可能的话,我会从字段/表名称中删除空格,并从查询字符串中删除所有方括号。
  • @SteveLovell - 未被识别为列名的标识符将被视为参数名称,无论它们是否包含在方括号中。不需要删除方括号。
  • 如果 SQL 解释器说你有一个语法错误,那么你就有一个语法错误。无论 PyCharm 说什么。在这个问题上,口译员永远是对的。
  • 感谢大家的回复!对不起,我有一段时间没有回到这里了。我添加了括号以排除任何潜在的命名错误。

标签: sql python-3.x ms-access pyodbc


【解决方案1】:

总的来说,两次查询尝试都存在几个问题:

  1. 将文字'_TZ______' 连接到您的最后一个参数值,因为占位符? 必须独立存在。
  2. 您需要为派生表 PreQuery 分配一个表别名,就像您在第一个查询中所做的那样。
  3. JOIN 必须位于新列别名 defect 上,而不是 Defect2
  4. WHERE 子句移动到子查询中。
  5. 删除GROUP BY 中的wk_no,因为它不是实际字段。常量不需要GROUP BY

考虑使用表别名进行以下语法调整,以减少长度和可读性。当然,没有数据,我无法充分测试。因此,您可能需要进一步调整:

qry = """
    SELECT ? AS [wk_no], [defect], SUM([qty_rej] + [qty_rew]) AS [qty_defect]
    FROM
      (
        SELECT s.[Date of Sort], p.[Part Name], d.[Defect2] AS [defect], 
               d.[Quantity Rejected] AS [qty_rej], d.[Quantity Reworked] AS [qty_rew]
        FROM (([Defect Table] d LEFT JOIN [Sort] s ON d.[Sort Number] = s.[Sort Number])
               LEFT JOIN [Part] p ON s.[Part Number] = p.[Part Number])
        WHERE ((s.[Date of Sort] BETWEEN ? AND ?) AND (p.[Part Name] LIKE ?))
      ) As PreQuery
    LEFT JOIN [Defects] ON [Defects].[Defect Code] = [PreQuery].[defect]        
    GROUP BY [defect];
"""   

cursor.execute(qry, myparams)  # WHERE LAST PARAM HAS '_TZ______' CONCATENATED TO ORIG VALUE

【讨论】:

  • “占位符 ? 必须独立存在” - 这实际上不是必需的。字符串参数实际上可以用作 SQL 命令文本中字符串表达式的一部分。
  • 感谢您的回复。我会执行您的建议并报告结果。
  • 您在FROM ... JOIN 部分缺少左括号。数着看。与其他方言不同,Access SQL 对括号括起来是严格的。初学者应该使用设计生成器在 MSAccess.exe GUI 程序中构建查询。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多