【问题标题】:Python - Multiple LIKE arguments in sqlite3Python - sqlite3 中的多个 LIKE 参数
【发布时间】:2021-09-23 04:20:44
【问题描述】:

我正在尝试在 tkinter 中从 sql 表创建搜索功能。

        for konto in sql_konto_search(db_file, "kontoplan", keywords):
            tv.insert('', tk.END, values=((konto[konto_q][0], konto[konto_q][1]), konto[konto_q][2]), tags=('fg', 'fs', 'bg', 'anch'))
            konto_q += 1
        if not keywords:
            tv.delete(*tv.get_children())
            tv_index()

这是我的 SQL 代码(函数)。我正在尝试创建一个正在搜索多个关键字的查询 - 但效果不佳。

def sql_konto_search(db_file, table, keywords):
keywords_split = keywords.split()
keywords_list = []
for keyword in keywords_split:
    keywords_list.append(keyword)
ant_que = len(keywords_list)
keywords_list = tuple(keywords_list)
try:
    rows = []
    conn = sqlite3.connect(db_file)
    cur = conn.cursor()
    xq = 0
    for ant_q in range(ant_que):
        cur.execute(f"SELECT konto, konto_t, beskrivelse FROM {table} WHERE konto_t LIKE ('%{keywords_list[xq]}%') OR beskrivelse LIKE ('%{keywords[xq]}%')")
        xq += 1
        rows.append(cur.fetchall())
    return rows
except Error as e:
    print(e)

如您所见,“关键字”是用户输入的关键字——我想搜索每个单词。 有什么建议吗?

【问题讨论】:

  • 不要使用 f-strings 来编写查询!这会使您的程序容易受到 SQL 注入攻击。
  • 所以当你输入的时候,你会搜索?
  • 是的@Sujay,但每个空格 ( ) 都会返回一个新关键字。
  • .strip() 被使用

标签: python sql tkinter


【解决方案1】:

你会希望这样的东西能够从你的关键字搜索字符串中正确地组成一个 SQL 查询。

这也正确地使用了参数替换,因此您的程序不再容易受到 SQL 注入问题的影响。 (我建议阅读sqlite3 module documentation;搜索“从不这样做”。)

import sqlite3


def sql_konto_search(db_file, table, keywords):
    # Get an unique set of keywords from the string
    keywords_set = set(keyword.strip() for keyword in keywords.split())

    # Initialize a list for the where clauses we'll OR together
    where_clauses = []
    # Initialize a list for the `?` parameter placeholders.
    parameters = []

    for keyword in keywords_set:
        # If the keyword is empty, skip it.
        if not keyword:
            continue
        # Add a parenthesized fragment for the search with two parameter placeholders...
        where_clauses.append("(konto_t LIKE ? OR beskrivelse LIKE ?)")

        # ... so add two parameters.
        keyword_wildcard = f"%{keyword}%"
        parameters.append(keyword_wildcard)
        parameters.append(keyword_wildcard)

    # Compose the final query. Start with the select...
    query_fragments = [f"SELECT konto, konto_t, beskrivelse FROM {table}"]
    if where_clauses:
        # and if there are where clauses, add the WHERE
        # and join the clauses with ORs (they're already parenthesized above)
        query_fragments.append(" WHERE ")
        query_fragments.append(" OR ".join(where_clauses))

    # Join the fragments into a single SQL statement...
    sql = "".join(query_fragments)

    print(sql, parameters)  # Just so you can see what happens.

    # ... and execute it.
    with sqlite3.connect(db_file) as db:
        cur = db.cursor()
        cur.execute(sql, parameters)
        return cur.fetchall()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-26
    • 2021-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-16
    相关资源
    最近更新 更多