0

我正在尝试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
4

3 回答 3

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条款!你刚刚改变field5每一行!那是问题 #1:您需要添加一个where子句。大多数表都有一个主键,所以如果你有一个主键,你可能想要添加一个像where id = ?. 如果您没有主键,您能做的最好的可能就是包括所有其他列,例如

update table1
set field5 = ?
where field1 = ?
and field2 = ?
and field3 = ?
and field4 = ?

确保为调用?中的每个提供一个值。execute


所以你已经完成了在游标上执行你的update语句。cur你再去迭代......并且没有更多的行。为什么?因为该update语句更改了游标的结果集,丢弃了select. 在继续更新之前,您需要在不同的游标上运行更新或获取所有行。

于 2013-07-21T22:26:49.017 回答
0

我知道这是一个古老且已解决的问题,但我无能为力:

这是用自己的列中的值更新表的更糟糕的方法。您需要做的就是在数据库中执行一条更新语句:

UPDATE table SET 
field1 = function(params1), 
field2=function(params2),   
field3=function(params3),   
field4=function(params4)
WHERE
<condition>

如果要对表中的所有行执行此操作,则不需要 where 子句。您唯一需要做的就是在您的数据库中定义一个用户函数,这与您在 python 中所做的非常相似。

这样,更新速度将快... 1000 倍,毫不夸张。

于 2014-02-07T14:42:50.153 回答
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)")
于 2021-01-24T12:59:10.637 回答