php 在预准备语句中使用INSERT INTO、ON DUPLICATE KEY和IF()时可能出现数据类型错误

ifmq2ha2  于 2022-11-21  发布在  PHP
关注(0)|答案(1)|浏览(127)

我正在尝试发送一种通知,以便在INSERT INTO,ON DUPLICATE KEY UPDATE查询过程中不更新字段,我在这篇文章中对此进行了概述。(Possible to do a MYSQL UPDATE query but not actually update a column?
我正在关注这个模型,它是作为对那个帖子的回复而提供的。(https://stackoverflow.com/a/74418601

UPDATE homes SET ..., name = if(?='DO NOT UPDATE',name,?) WHERE id=?
$stmt2->execute([..., $row['name'], $row['name'], $row['id']]);

问题是,它似乎(不确定)有类型错误,在我自己去遵循这个模型。

$stmt = "INSERT INTO user (id, state, age) 
VALUES (?, ?, ?),(?, ?, ?) AS foo_baz
ON DUPLICATE KEY UPDATE 
name = if(foo_baz.name='DO NOT UPDATE', user.name, foo_baz.name),
age = if(foo_baz.age='DO NOT UPDATE', user.age, foo_baz.age)";

$data = [1, 'Oregon', 55, 2, 'Washington', 'DO NOT UPDATE'];

$sql = $pdo->prepare($stmt);
$sql->execute($data);

id列的数据类型是signed int,state列是varchar,age是signed int。
当我运行这个程序时它说

"Invalid datetime format: 1292 Truncated incorrect DOUBLE value: " for the age column

这可能是因为'DO NOT UPDATE'被放置在int列age中。
INSERT INTO,ON DUPLICATE KEY UPDATE只被用作方式更新。所有要插入的数据都已经有一行具有已存在的主键,因此没有实际的插入。如果它是实际的插入,则该错误将是有意义的,因为它将尝试将错误的数据类型插入字段。但是由于它只是更新,数据实际上并没有被插入(因为它是“不更新”)。我读到mysql在执行INSERT INTO,ON DUPLICATE KEY UPDATE查询时试图插入然后在内部更新。
我确实尝试过转换变量,但是错误重复出现,因为错误可能出现在查询的INSERT部分,在查询的ON DUPLICATE KEY UPDATE部分之前。(这可能根本不起作用,因为'DO NOT UPDATE'不是int,并且可能总是给出假否定或假肯定。)

age = if(foo_baz.age=CAST('DO NOT UPDATE' AS SIGNED), user.age, foo_baz.age)

如果我正确地解释了错误(不确定),我想要完成的是一种技术,(不一定是DO NOT UPDATE)到$data中,以获得我不希望它更新的值,并且有一种方法来指示对于ANY数据类型列,因此任何关于如何修复我所做的事情或以其他方式完成这一工作的建议都是有帮助的,ON DUPLICATE KEY UPDATE查询。

uinbv5nw

uinbv5nw1#

如果您想完成与前面的相关帖子相同的事情(使用sql if()来确定要更新的值),请更改以下内容

$stmt = "INSERT INTO user (id, state, age) 
VALUES (?, ?, ?),(?, ?, ?) AS foo_baz
ON DUPLICATE KEY UPDATE 
......

$stmt = "INSERT INTO user (id, state, age) 
VALUES (?, ?,  if(?='DO NOT UPDATE',age,?)),(?, ?,  if(?='DO NOT UPDATE',age,?)) AS foo_baz
ON DUPLICATE KEY UPDATE 
......

并确保传递age的值(可能是DONOTUPDATE),以便对每条记录执行两次
所以从

$data = [1, 'Oregon', 55, 2, 'Washington', 'DO NOT UPDATE'];

$data = [1, 'Oregon', 55, 55, 2, 'Washington', 'DO NOT UPDATE', 'DO NOT UPDATE'];

相关问题