执行多行插入时出现重复键更新错误: 并未使用全部参数。

4

我一直在尝试使用python 2.7.15和mysql.connector执行这个查询。但是由于某些原因,它似乎无法运行,并且始终返回错误:未使用所有参数。

表'updates'有一个主键,即“ID”

这是我尝试运行的SQL查询:

sql = "INSERT INTO updates (ID, insert_datetime, egroup, job_state) VALUES (%s,%s,%s,%s) ON DUPLICATE KEY UPDATE insert_datetime = VALUES(%s), egroup = VALUES(%s), job_state = VALUES(%s);"
mycursor.executemany(sql, jobUpdatesList)

这是jobUpdatesList数组中一个数组的样子:
[u'17281725', datetime.datetime(2018, 9, 10, 16, 11, 45, 724000), u'language', u'R', datetime.datetime(2018, 9, 10, 16, 11, 45, 724000), u'language', u'R']

我这样做是因为我认为需要7个参数,因为我有7个%s。

我也尝试过只使用4个参数,就像这样:

sql = "INSERT INTO updates (ID, insert_datetime, egroup, job_state) VALUES (%s,%s,%s,%s) ON DUPLICATE KEY UPDATE ID = VALUES(%s), insert_datetime = VALUES(%s), egroup = VALUES(%s), job_state = VALUES(%s);"
mycursor.executemany(sql, jobUpdatesList)

这是jobUpdatesList数组中一个数组的样子:
[u'17281725', datetime.datetime(2018, 9, 10, 16, 18, 9, 268000), u'language', u'R']

但是我遇到了以下错误:
mysql.connector.errors.ProgrammingError: 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '%s), egroup = VALUES(%s), job_state = VALUES(%s)' at line 1

我曾尝试将VALUES(%s)替换为'%s'来修复此错误,结果成功了。但是所有字段都被%s替换了,而不是值。我还尝试了不带引号的%s,例如:egroup = %s,但是仍然出现了相同的错误。

我尝试了很多方法,但似乎无法使其正常工作。我做错了什么?


你不能使用位置参数绑定列名;这是你的代码失败的直接原因。但是,你能告诉我们当插入重复的“ID”时应该发生什么逻辑吗? - Tim Biegeleisen
@TimBiegeleisen 首先,我需要插入所有最新的项目,如果已经存在一个项目,则希望更新该行的信息,以使其再次更新。我也是用这种方式进行插入语句的,并且它们确实有效,因此我认为问题出在了ON DUPLICATE KEY部分。 - RamonRobben
我不同意,详见下面的回答。 - Tim Biegeleisen
1个回答

7
无法使用位置参数来表示实际列名;由于许多原因,需要在语句中硬编码列名。但是,在您的情况下,这样做没有任何问题:
INSERT INTO updates (ID, insert_datetime, egroup, job_state)
VALUES (%s,%s,%s,%s)
ON DUPLICATE KEY UPDATE
    insert_datetime = VALUES(insert_datetime),
    egroup = VALUES(egroup),
    job_state = VALUES(job_state);

或者,作为Python代码:

sql = "INSERT INTO updates (ID, insert_datetime, egroup, job_state) VALUES (%s,%s,%s,%s) ON DUPLICATE KEY UPDATE insert_datetime = VALUES(insert_datetime), egroup = VALUES(egroup), job_state = VALUES(job_state);"
mycursor.executemany(sql, jobUpdatesList)

1
是的,这解决了我的问题。我以为mysql库会用数组中各自的值替换所有的%s符号,因为当我引用它们时它们确实起作用。所以我尝试使用7个参数。现在这更有意义了。谢谢! - RamonRobben
嗨。我能以某种方式做到这一点,而不必命名所有那些“VALUES(insert_datetime)”的东西吗? - Gh0sTG0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接