sqlite 如何格式化引用列名的UPDATE查询?

af7jpaap  于 2023-10-23  发布在  SQLite
关注(0)|答案(1)|浏览(119)

我的函数迭代表中包含的列名列表并运行选择查询。然后遍历每条记录,并将字段值与清理后的版本进行比较。如果它们不同,我需要运行一个UPDATE查询,将清理后的值写入该记录。我无法使UPDATE查询工作。另一个使用以下查询执行类似操作的函数:

dbcursor.execute('''UPDATE alib set live = (?) WHERE rowid = (?);''', (islive, row_to_process))

不同之处在于需要迭代列名。我已经了解到不能将变量作为字段名传递给SELECT语句,因此我动态地构建了查询字符串。那也行更新查询则是另一回事:

for text_tag in text_tags:

    dbcursor.execute('''CREATE INDEX IF NOT EXISTS dedupe_tag ON alib (?) WHERE (?) IS NOT NULL;''', (text_tag, text_tag))
    print(f"- {text_tag}")

    ''' get list of matching records '''
    ''' as you cannot pass variables as field names to a SELECT statement build the query string dynamically then run it '''
    query = f"SELECT rowid, {text_tag} FROM alib WHERE {text_tag} IS NOT NULL;"
    dbcursor.execute(query)

    ''' now process each matching record '''
    records = dbcursor.fetchall()
    records_returned = len(records) > 0
    if records_returned:
          
        for record in records:
            <SNIP>

                if final_value != stored_value_sorted:

                    ''' write out {final_value} to column {text_tag} for record = rowid '''
                    row_to_process = record[0]
                    query = SEE QUERIES BELOW THIS CODE SNIPPET
                    print(query) # temp code to see what query is generated
                    dbcursor.execute(query)

我尝试了3种不同的UPDATE查询,每种都抛出不同的错误。要写入的值可以有任意数量的\'"[]()和标点符号。第77行是dbcursor.execute(query)

query = f"UPDATE alib SET {text_tag} = (?) WHERE rowid = (?);", (final_value, row_to_process)
('UPDATE alib SET artist = (?) WHERE rowid = (?);', ('8:58\\\\The Unthanks', 305091))
Traceback (most recent call last):
  File "<string>", line 80, in <module>
  File "<string>", line 77, in dedupe_fields
TypeError: execute() argument 1 must be str, not tuple
query = f"UPDATE alib SET {text_tag} = '{final_value}' WHERE rowid = {row_to_process};"
UPDATE alib SET recordinglocation = 'Ashwoods, Stockholm\\Electric Lady Studioss, Stockholm\\Emilie's, Stockholm\\Ingrid Studioss, Stockholm\\Judios Studioss, Stockholm\\Nichols Canyon Houses, Stockholm\\Ocean Way Studioss, Stockholm\\RAK Studios, London\\Studio De La Grande Armée, Paris\\The Villages, Stockholm\\Vox Studioss, Stockholm' WHERE rowid = 124082;
Traceback (most recent call last):
  File "<string>", line 80, in <module>
  File "<string>", line 77, in dedupe_fields
sqlite3.OperationalError: near "s": syntax error
query = f"UPDATE alib SET {text_tag} = {final_value} WHERE rowid = {row_to_process};"
UPDATE alib SET artist = 8:58\\The Unthanks WHERE rowid = 305091;
Traceback (most recent call last):
  File "<string>", line 80, in <module>
  File "<string>", line 77, in dedupe_fields
sqlite3.OperationalError: near ":58": syntax error
xe55xuns

xe55xuns1#

问题在于query变量是如何定义的:
这是一个 tuple

query = f"UPDATE alib SET {text_tag} = (?) WHERE rowid = (?);", (final_value, row_to_process)

因此这:

dbcursor.execute(query)

实际上就是

dbcursor.execute((sql, values))

因此,您将单个对象(元组)传递给executeexecute假设它是查询字符串,因此会出错。
相反,解压缩元组,使execute接收两个单独的参数:

dbcursor.execute(*query)

相关问题