<p>是的,您告诉数据库用相同的<code>framenum</code>更新<strong>所有</strong>行。这是因为<code>UPDATE</code>语句没有选择任何特定的行。您需要告诉数据库一次更改一行,方法是为每个值包含一个主键。在</p>
<p>因为您只更改特定的帧编号,所以可以要求数据库只提供这些特定的行,而不是遍历所有行。您可能还需要指定一个<em>顺序</em>来更改数字;也许您需要以递增framenumber顺序执行此操作?在</p>
<pre><code>c.execute("""
SELECT rowid, framenum FROM learnAlg
WHERE framenum in ({})
ORDER BY framenum
""".format(', '.join(['?'] * len(change_numbers))),
change_numbers)
update_cursor = conn.cursor()
for change, (rowid, f) in enumerate(c, 1):
update_cursor.execute("""
UPDATE learnAlg SET framenum=? WHERE rowid=?""",
(f + change, rowid))
</code></pre>
<p>我在这里稍微修改了结构;查询通过<code>WHERE IN</code>子句,仅将结果限制为<code>change_numbers</code>序列中的帧编号。我直接在光标上循环(不需要一次获取所有结果),并使用单独的<code>UPDATE</code>s来设置新的帧编号。我用<code>enumerate()</code>代替手动计数器来记录计数。在</p>
<p>如果需要按<code>change_numbers</code>对更新进行分组,那么只需告诉数据库执行这些更新:</p>
^{pr2}$
<p>从最高的帧编号开始,以避免更新之前已更新的帧编号。这假定您的<code>change_numbers</code>是按递增顺序排序的。在</p>
<p>您的<code>executemany</code>更新应该只传入整个列表,而不仅仅是前两项;您确实需要更改附加值的方式:</p>
<pre><code>for e, f in enumerate(db_framenum):
# ...
db_framenum_new.append((t, e)) # framenum first, then rowid
c.executemany("UPDATE learnAlg SET framenum=? WHERE rowid=?",
db_framenum_new)
</code></pre>
<p>注意,<code>executemany()</code>调用发生在<code>for</code>循环之外的<em>之外!在</p>