我正在尝试使用函数的结果UPDATE
表的所有记录,该函数使用表的其他行作为参数。但是,从第一个记录开始重复对所有记录执行此操作的结果。任何人都可以解释为什么会出现这种情况吗?
def fun(a,b,c,d):
return a + b + c + d
cur = conn.cursor()
cur.execute("SELECT field1, field2, field3, field4 FROM TABLE1")
for row in cur:
cur.execute("UPDATE TABLE1 SET field5 = ?", (fun(row[0],row[1],row[2],row[3]),))
完成的表格如下所示:
field1, field2, field3, field4, field5
4, 3, 2, 1, 10
7, 3, 1, 0, 10
8, 5, 2, 0, 10
什么时候看起来像这样:
field1, field2, field3, field4, field5
4, 3, 2, 1, 10
7, 3, 1, 0, 11
8, 5, 2, 0, 15
答案 0 :(得分:2)
首先,选择所有行:
SELECT field1, field2, field3, field4 FROM TABLE1
这会在cur
:
4, 3, 2, 1
7, 3, 1, 0
8, 5, 2, 0
您开始遍历行。你从第一行开始:
4, 3, 2, 1
将所有列添加到一起,正确生成结果10
。然后执行此SQL语句:
UPDATE TABLE1 SET field5 = 10
哇,哇!没有where
条款!您刚刚更改了每一行的<{1}} !这是问题#1:您需要添加field5
条款。大多数表都有主键,因此如果您有主键,则可能需要添加类似where
的子句。如果您没有主键,那么您可以做的最好的事情就是包括所有其他列,例如
where id = ?
确保您为update table1
set field5 = ?
where field1 = ?
and field2 = ?
and field3 = ?
and field4 = ?
来电中的每个?
提供了一个值。
所以你已经在execute
光标上执行了update
语句。你再去迭代......而且没有更多的行了。为什么?因为cur
语句更改了游标的结果集,所以丢弃了update
的剩余行。 您需要在不同的光标上运行更新或获取所有行,然后再继续更新。
答案 1 :(得分:0)
我知道这是一个古老且已解决的问题,但我无法帮助它:
这是使用自己的列更新表的更糟糕的方法。您需要做的就是在数据库中执行一个单独的更新语句:
UPDATE table SET
field1 = function(params1),
field2=function(params2),
field3=function(params3),
field4=function(params4)
WHERE
<condition>
如果要对表中的所有行执行此操作,则不需要where子句。您唯一需要做的就是在数据库中定义一个用户函数,这与您在python中的操作非常相似。
这样,更新速度将提高约1000倍,毫不夸张。
答案 2 :(得分:0)
只需将该函数添加到您的数据库中:
conn = sqlite3.connect("database.db")
def fun(a,b,c,d):
return a + b + c + d
conn.create_function(
cur = conn.cursor('fun', 4, fun)
cur = conn.cursor()
cur.execute("UPDATE table SET field5 = fun(field1, field2, field3, field4)")