首页 > 解决方案 > 带通配符的 PyODBC 查询

问题描述

我正在尝试通过 Python 使用 LIKE 运算符运行 SQL 查询,以查找在任何位置具有“测试”的任何值。问题似乎在于 LIKE 运算符之后的格式。没有错误消息,查询只是空的。

我试图模仿的 SQL 查询如下,并且在 Access 上执行时有效。

SELECT Areas.ID, Areas.Name
FROM Areas
WHERE Name LIKE '*test*'

以下是连接和测试数据的制作方式。里面没有问题。

import pyodbc

# Connect to database
conn_str = (
    r'DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};'
    r'DBQ=C:\Temp\TestDB.accdb;'
    r'Uid=;'
    r'Pwd=;'
    )

# Make cursor
connection = pyodbc.connect(conn_str)
connection.setencoding('utf-8')
cursor = connection.cursor()

# Create test table
cursor.execute("CREATE TABLE Areas (ID integer, Name varchar(255))")
connection.commit()

# Create test data 
cursor.execute("INSERT INTO Areas (ID, Name) VALUES (1,'Example_1');")
cursor.execute("INSERT INTO Areas (ID, Name) VALUES (2,'Example_test_2');")
cursor.execute("INSERT INTO Areas (ID, Name) VALUES (3,'Example_3');")
connection.commit()

# Query filter
Filter = "'*test*'"

尝试01

query_01 = cursor.execute(r"""
        SELECT Areas.ID, Areas.Name
        FROM Areas
        WHERE Name LIKE {Filter}
        """.format(Filter=Filter)).fetchall()
for row in query_01:
    print(row)

尝试02

query_02 = cursor.execute(r"""
        SELECT Areas.ID, Areas.Name
        FROM Areas
        WHERE Name LIKE ?
        """,("%{}%".format(filter),)).fetchall()
for row in query_02:
    print(row)

尝试03,我希望过滤器是可变的,但即使“硬编码”也不起作用。

query_03 = cursor.execute(r"""
        SELECT Areas.ID, Areas.Name
        FROM Areas
        WHERE Name LIKE '*test*'
        """).fetchall()
for row in query_03:
    print(row)

为了确保某些东西正常工作,我运行了它并打印了行。

query_04 = cursor.execute(r"""
        SELECT Areas.ID, Areas.Name
        FROM Areas
        WHERE Name = 'Example_test_2'
        """).fetchall()
for row in query_04:
    print(row)

理想的解决方案是过滤器变量可以只是一个字符串,没有通配符。我应该如何格式化过滤器变量和查询?

标签: pythonsqlms-accesswildcardpyodbc

解决方案


由于历史原因,LIKE从 Access UI 中运行的查询默认使用*?作为通配符。但是,使用 ODBC 查询 Access 数据库的外部应用程序必须使用更常见的%通配符_

此外,参数必须包含通配符。(LIKE没有通配符的条件与=条件相同。) SQL 命令文本中的参数占位符必须是一个空问号?

最后,不要使用connection.setencoding('utf-8'). Access 将文本值存储为 Unicode,但它不使用UTF-8 编码。默认的 pyodbc 编码 (UTF-16) 工作得很好。

所以你要找的是

filter = 'test'
sql = "SELECT Areas.ID, Areas.Name FROM Areas WHERE Areas.Name LIKE ?"
param = f'%{filter}%'
rows = cursor.execute(sql, param).fetchall()

推荐阅读